【问题标题】:In Qt, does a QThread's event loop block while a slot on a QObject owned by the event loop's thread is executing?在 Qt 中,当事件循环线程拥有的 QObject 上的插槽正在执行时,QThread 的事件循环是否阻塞?
【发布时间】:2013-06-07 17:26:36
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-18
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 2016-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多