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

In Qt, does a QThread's event loop block while a slot on a QObject owned by the event loop's thread is executing?

本文关键字:事件 循环 执行 是否 QThread QObject Qt 循环线 线程 拥有 插槽      更新时间:2023-10-16

我想确认一下我认为Qt中工作线程的一个直截了当的方面。

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

就是(从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()信号接收触发器,以便在task实例上调用deleteLater()槽。此外,该事件循环将在doWork()函数返回后不久运行,因此它将准备好并可用于处理finished()信号的触发器,该信号刚刚通过在doWork()函数末尾调用finished()添加到工作线程的事件队列中。

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

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

谢谢!

工作线程的事件循环将被阻塞,即你将无法处理任何事件(包括那些用于信号和插槽之间的'排队'连接的事件,这是你在跨线程进行信号-插槽连接时得到的),除非你显式地触发对事件循环对象的调用。

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