QThread:如何停止无限循环
我在Qthread中执行一个花费大约3个小时的图像处理过程,而没有可能将一些检查点放入它的出口门。问题是我无法阻止它。这个代码表示这个问题:QThread:如何停止无限循环
class Toto : public QObject
{
Q_OBJECT
public slots:
void exec(){
//I represent the real process with an infinite loop
while(1==1);
}
};
int main(int argc, char *argv[])
{
QApplication aa(argc, argv);
QThread * t1 = new QThread;
Toto * toto1 = new Toto;
QThread * t2 = new QThread;
Toto * toto2 = new Toto;
QPushButton push;
push.show();
toto1->moveToThread(t1);
toto2->moveToThread(t2);
QMetaObject::invokeMethod(toto1, "exec", Qt::QueuedConnection);
QMetaObject::invokeMethod(toto2, "exec", Qt::QueuedConnection);
QApplication::connect(&push, SIGNAL(pressed()), t1,SLOT(terminate()), Qt::QueuedConnection);
QApplication::connect(&push, SIGNAL(pressed()), t2,SLOT(terminate()), Qt::QueuedConnection);
t2->start();
t1->start();
return aa.exec();
}
感谢您的帮助
线程将永远不会处理终止()信号,因为高管插槽不会返回控制线程的事件循环。
相反,您应该在QApplication的主循环中运行的对象中创建一个槽。将按钮连接到该插槽,然后在适当的线程对象上调用terminate()。
其实,调用terminate()是不好的做法。相反,你的无限循环应该有一些标志,它定期检查,如果该标志设置,你跳出循环。当然,您可以更改线程中另一个函数内的标志。你可能也想看看QtConcurrent来解决这类长时间运行的任务。 – 2012-02-24 13:14:07
是的,但是如果我的插槽位于QApplication的主循环中,我失去了并发任务:/ – Vincent 2012-02-24 13:39:50
感谢Trenton Schulz但是,我的无限循环表示我的图像处理库超过两百种算法。我无法为每个人添加一个中断点。在其他多线程库中,我们可以将线程杀死为没有标志的“海盗”。 – Vincent 2012-02-24 13:40:49
根据文档,您需要先调用void setTerminationEnabled (bool enabled = true)
方法并启用终止。否则终止将被推迟。
真的,根据文档,“线程可以在其代码路径中的任何点终止。”但是,当你尝试它时,没有任何反应。谢谢 – Vincent 2012-02-24 15:59:19
所以你试图启用终止,没有什么帮助?你是否尝试从你的主线程中调用't1-> terminate();'?例如。 'QApplication :: connect(&push,SIGNAL(pressed()()),这个,SLOT(terminateAllThreads())); void terminateAllThreads(){t1-> terminate(); }' – Dmitriy 2012-02-24 16:14:18
我尝试几乎所有的可能性,甚至这一个。 – Vincent 2012-02-24 16:26:05
哲学上讲,如果一个人能够阻止它,东西不会是一个无限循环。 – Jake 2012-02-24 12:59:52
无限中的线程参考!!! ;) – Vincent 2012-02-24 13:49:04
我已经构建了您的示例代码,它的工作原理,线程终止。 Windows 7,Qt 4.7.4 – Dmitriy 2012-02-24 20:10:46