关于在我的应用程序中实现QThread的问题?

时间:2012-03-15 20:53:56

标签: c++ qt mingw qthread

正如this question中所建议的那样,我现在正试图融入多线程。

根据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中的quit()退出(我希望我在这里没有犯错误)。我认为该线程不再存在。

  3. 执行th的插槽finished()后,可以安全地假设该线程确实已退出,或者是否应进一步连接th {{1}}信号到某个位置绝对确定?

2 个答案:

答案 0 :(得分:1)

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

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

      

    如果targetThread为零,则此对象及其子对象的所有事件处理都将停止。

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

答案 1 :(得分:0)

1。如果我在someFunct()内发出over()之后继续使用someFunct()会怎样?它是未定义的行为还是正常的?

当您使用直接连接时,发出over将直接调用函数quit停止事件循环并从线程运行方法中的exec返回。这意味着someFunct()将无法完成其执行,并且其中的对象要么丢失,要么处于部分修改状态。

2。 obj现在与哪个线程相关联(发出over()之后的其余代码仍在someFunct中执行)?

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

3。一旦执行了插槽quit(),是否可以安全地假设线程确实已退出,或者我是否应该将th的完成()信号连接到某个插槽以确保绝对可靠?

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

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

无论如何,这些都是一些很棒的问题......