在Qt中,当事件循环的线程拥有的QObject上的一个槽正在执行时,QThread的事件循环是否阻塞?

时间:2013-06-07 17:26:36

标签: c++ multithreading qt signals-slots event-loop

我想确认一下我认为Qt中工作线程的直接方面。

假设我创建了一个QThread,其目的是在相应的线程中管理耗时的工作。此外,假设我通过调用QThread上的start()来允许此线程的相应事件循环运行。工作本身由成员函数(插槽)执行,该函数由QThread的started()信号发出信号。

那是(从https://stackoverflow.com/a/11039216/368896复制):

class Task : public QObject
{
Q_OBJECT
public:
    Task();
    ~Task();
public slots:
    void doWork()
    {
        //very time-consuming code is executed here before the next line is reached...
        emit workFinished(); // Calls workFinished() signal (after a long time)
    }
signals:
    void workFinished();
};

// ... in the main thread:
QThread *thread = new QThread( );
Task    *task   = new Task();
task->moveToThread(thread);
connect( thread, SIGNAL(started()), task, SLOT(doWork()) );
connect( task, SIGNAL(workFinished()), thread, SLOT(quit()) );
//automatically delete thread and task object when work is done:
connect( thread, SIGNAL(finished()), task, SLOT(deleteLater()) );
connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()) );
thread->start();

我的问题如下。我知道工作线程的事件循环将从finished()信号接收一个触发器,以便调用deleteLater()实例上的task插槽。此外,此事件循环将在doWork()函数返回后很快运行,因此它将准备好并可用于处理来自刚添加到工作线程事件队列的finished()信号的触发器通过finished()函数末尾的doWork()调用。

我想确认在doWork()内部(finished()发出之前和doWork()函数退出之前)执行耗时操作的整个过程中,工作线程中的事件循环在插槽函数doWork()上被阻止,因此工作线程将响应任何由所拥有的任何对象触发的插槽在执行耗时的doWork()函数的整个过程中,事件循环的线程。 (因此,任何此类插槽只会在doWork()退出后,一旦工作线程的事件循环再次激活,并且在处理finished()信号的触发之前执行。)

我怀疑是这种情况,但我想确认一下。

谢谢!

1 个答案:

答案 0 :(得分:7)

工作线程的事件循环将被阻止,即您将无法处理任何事件(包括那些用于信号和插槽之间“排队”连接的事件,这是您在执行信号时获得的事件 - 除非您自己明确地触发对事件循环对象的调用,否则将跨越线程进行插槽连接。

但是,您仍可以在工作线程中执行插槽,这些插槽由工作线程发出的信号触发,因为它们是普通函数调用,不需要运行事件循环。