gpt4 book ai didi

c++ - 不正确地终止线程?

转载 作者:行者123 更新时间:2023-11-28 02:08:02 25 4
gpt4 key购买 nike

我有一个正在并行化的 n 体模拟。我正在使用 QT,所以我有一个自定义 QObject 类,它具有我已并行化的过程。它由线程内的另一个 QObject 控制,该线程仅处理该线程。问题是每次一个物体与另一个物体碰撞时,所有线程都必须停止,以便它们可以被删除,并用不同的行星系统重新创建。

这是线程处理程序类的源代码:

#include "threadhandler.h"
#include <QEventLoop>
#include "subprocess.h"
#include <QThread>
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>

ThreadHandler::ThreadHandler(double scopeX, double scopeY)
{
int size = 100;
int idealNum = QThread::idealThreadCount();
int sizeForEach = size/idealNum;

for(int i = 0 ; i< idealNum ;i++){
SubProcess* tempSub = new SubProcess(i*sizeForEach, (i+1)*sizeForEach, scopeX, scopeY);
QThread* tempThread = new QThread;
tempSub->moveToThread(tempThread);
QEventLoop::connect(tempSub, SIGNAL(finished()), tempThread, SLOT(deleteLater()));
QEventLoop::connect(tempThread, SIGNAL(started()), tempSub, SLOT(process()));
QEventLoop::connect(tempThread, SIGNAL(finished()), tempSub, SLOT(deleteLater()));
QEventLoop::connect(tempSub, SIGNAL(collided()), this,
SLOT(refactorObjects()));
ThreadHandler::threads.push_back(tempThread);
ThreadHandler::objects.push_back(tempSub);
}
}

void ThreadHandler::process(){
std::cout << ThreadHandler::threads.size() << std::endl;
for(int i = 0; i < ThreadHandler::threads.size(); i++){
std::cout << "starting " << i+1 << std::endl;
ThreadHandler::threads.at(i)->start();
}
}

void ThreadHandler::refactorObjects(){
SubProcess::condition = false;
std::this_thread::sleep_for(std::chrono::seconds(1));
for(int i = 0 ; i < ThreadHandler::threads.size() ; i++){
ThreadHandler::threads.at(i)->terminate();
}
ThreadHandler::objects.clear();
SubProcess::sys.push_back(Body::collide(SubProcess::collidedAr.at(0), SubProcess::collidedAr.at(1)));
SubProcess::sys.erase(std::remove(SubProcess::sys.begin(), SubProcess::sys.end(),
SubProcess::collidedAr.at(0)), SubProcess::sys.end());
SubProcess::sys.erase(std::remove(SubProcess::sys.begin(), SubProcess::sys.end(),
SubProcess::collidedAr.at(1)), SubProcess::sys.end());

int idealNum = QThread::idealThreadCount();
int sizeForEach = SubProcess::sys.size() / idealNum;
for(int i = 0 ; i < idealNum ; i++){
SubProcess* tempSub = new SubProcess(i*sizeForEach, (i+1)*sizeForEach);
tempSub->moveToThread(ThreadHandler::threads.at(i));
ThreadHandler::objects.push_back(tempSub);
QEventLoop::connect(tempSub, SIGNAL(finished()), ThreadHandler::threads.at(i), SLOT(deleteLater()));
QEventLoop::connect(ThreadHandler::threads.at(i), SIGNAL(started()), tempSub, SLOT(process()));
QEventLoop::connect(ThreadHandler::threads.at(i), SIGNAL(finished()), tempSub, SLOT(deleteLater()));
QEventLoop::connect(tempSub, SIGNAL(collided()), this,
SLOT(refactorObjects()));
}

for(int i = 0; i < idealNum; i++){
ThreadHandler::threads.at(i)->start();
}
std::cout << "refactored" << std::endl;
}

这是子流程的来源:

#include "subprocess.h"
#include <iostream>

std::vector<Body> SubProcess::sys;
std::vector<Body> SubProcess::collidedAr;
double SubProcess::timeScale;
bool SubProcess::condition = true;


SubProcess::SubProcess(double start, double end, double scopeX, double scopeY){
for(int i = start; i< end; i++){
SubProcess::sys.push_back(Body::createRandomBody(scopeX, scopeY));
}
this->start = start;
this->end = end;
}
SubProcess::SubProcess(double start, double end){
this->start = start;
this->end = end;
}

void SubProcess::process(){
while(SubProcess::condition){
for(int i = start; i < end ; i++){
for(int j = 0; j < SubProcess::SubProcess::sys.size() ; j++){
if(!(SubProcess::sys.at(i)==SubProcess::sys.at(j))){
double F = Body::getForce(SubProcess::sys.at(i), SubProcess::sys.at(j));
if (F!=-1){
double dX = SubProcess::sys.at(i).getX()-SubProcess::sys.at(j).getX();
double dY = SubProcess::sys.at(i).getY()-SubProcess::sys.at(j).getY();
SubProcess::sys.at(i).exertForce(-dY, -dX, F, timeScale);
} else {
SubProcess::collidedAr.clear();
SubProcess::collidedAr.push_back(SubProcess::sys.at(i));
SubProcess::collidedAr.push_back(SubProcess::sys.at(j));
SubProcess::condition = false;
emit collided();
}
}
}
SubProcess::sys.at(i).tick(timeScale);
}
}
emit finished();
}

每当我运行它时,它都能完美运行,直到我得到的碰撞点:

starting 1
starting 2
starting 3
starting 4
refactored
refactored
QThread: Destroyed while thread is still running
QThread: Destroyed while thread is still running
QThread: Destroyed while thread is still running
QThread: Destroyed while thread is still running

所以对我来说没有意义的是线程在重构过程开始时被删除,并且不会产生错误。但由于某种原因,在新线程启动后,某些东西正在结束它们。我完全不知道这里发生了什么。我认为我没有正确处理和重新创建线程,应该有更好的方法。

最佳答案

一般来说,终止正在运行的线程会导致未定义的行为(与在其他数据一致的状态下被阻塞的线程相反)。你不应该终止线程。只需对子进程执行 deleteLater,它们就会自动清除。他们的线程不会受到影响。参见 this answer为什么可以在其他线程中的对象上调用 deleteLater

您应该保留一个线程池以供重用,无需重新创建它们。您甚至可以为此重用 QThreadQueue

默认的 QThread 销毁是非常不安全的,您应该使用 a version without that deficiency相反,如果可以的话。

关于c++ - 不正确地终止线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36750448/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com