2012-03-15 59 views
2

正如this question中所建议的那样,我现在正在尝试合并多线程。关于在我的应用程序中实现QThread的问题?

根据the links given by karlphillip,我知道不应遵循有关继承QThread的文档,并按照说明使用moveToThread()。现在我看到QThread run()的默认实现只有一个exec(),然后必须在工作线程完成操作时调用quit()来结束。我有几个问题,现在让我更好地了解事情:

QApplication* ptrApp=new QApplication(argc,argv); 
QThread* th=new QThread; 
MyClass* obj=new MyClass; 
obj->moveToThread(th); 
QObject::connect(th,SIGNAL(started()),obj,SLOT(someFunct())); 
QObject::connect(obj,SIGNAL(over()),th,SLOT(quit())); 
th->start(); 
//some GUI code in main thread here 
return ptrApp->exec(); 
  1. ,如果我继续使用someFunct()我发出over()即使从someFunct()内会发生什么?它是未定义的行为还是正常的?

  2. 哪个线程现在应与obj关联(而发出over()后的其余代码仍在someFunct中执行)?我的理解是:它不能在th,当我有quit()那个线程... quit()将排队,直到exec()在主线程执行它,这将导致exec()run()th退出(我希望我不是一个错误在这里)。我假设线程不再存在。

  3. 一旦th插槽quit()执行,是安全的假设线程确实已经退出,还是应该我的thfinished()信号进一步连接到某些插槽是绝对肯定吗?

回答

0

1.如果我继续使用someFunct()我发出over()即使从someFunct()内会发生什么?它是未定义的行为还是正常的?

当你正在使用直接连接,发射over将直接调用该函数quit其停止事件循环,并从EXEC在线程的run方法返回。这意味着someFunct()将不会完成其执行并且其中的对象将丢失或处于部分修改状态。

2.哪个线程会obj现在被关联(而在发射over()之后的其余代码仍然在someFunct中执行)?

如前所述somefunct将不会完成其执行。但我相信任何与此线程相关的对象将保持原样。我说我相信,因为在任何地方都没有坚实的断言,但它最有意义。 As mentioned in the doc,对于这些对象发送或接收事件的线程必须重新启动....

3.一旦执行插槽退出()执行,是否可以安全地假设线程确实退出或应该我进一步将完成的()信号连接到某个插槽以绝对确定?

quit()终止事件循环并返回exec()被调用。

请注意,对象Qthread不是线程。所以直到你输入exec(),它是正在运行的主线程...以及它是在exec之后运行的主线程。

反正这些都是一些重大问题...

1
  1. 如果事件循环终止不要紧,somefunct()将继续运行,直到它给控制权交还给现已灭绝循环。

  2. obj保持与线程关联,因此如果发射连接到其中一个插槽的信号,该插槽将不会运行,但会在/重新启动线程时排队。
    如果QThread对象被删除,obj->thread()返回0,所以我想这将是等效于调用obj->moveToThread(0)并根据文档:

    如果targetThread为零,所有针对这个对象的事件处理及其子站。

  3. quit()终止事件循环,则finished()信号从线发射,并且线程终止。
    因此,即使您收到finished()信号,您也不应该认为线程已完成。在收到该信号后,您可以使用主线程中的QThread::wait来确保。
    如果线程处于完成状态,QThread析构函数已经调用wait,因此您可以安全地删除finished()信号后的线程(使用deleteLater()更安全)。

+0

感谢 1.亚这就是我被注意到的行为......只是想确保它不是未定义/非法或东西 2.确定...请告诉我,如果我删除会发生什么QThread指针'th'(现在因为我们不能重新启动线程了,我想) 3. for'quit()'我明白,它将在队列中执行直到'exec()'在主线程中执行它...但'finished()'是一个不需要任何事件循环的信号,它是终止线程所要做的最后一件事情,为什么需要另外指定'QThread :: wait()'使用'finished()'信号? – ustulation 2012-03-16 11:59:41

+0

对于2.您可以根据需要随时停止并重新启动线程。对于3.发射信号不需要事件循环。无论如何,连接它的插槽应该在另一个线程中运行事件循环(线程eventloop不能接收到它自己的finished()信号)。但在查看QThread的来源后,我认为在大多数情况下,您可以等待完成的信号。 – alexisdm 2012-03-16 14:21:52

相关问题