6

我想确认一下我认为 Qt 中工作线程的一个简单方面。

假设我创建了一个 QThread,其目的是管理其相应线程中的耗时工作。start()此外,假设我通过调用QThread来允许该线程的相应事件循环运行。工作本身由 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()处理来自信号的触发器之前执行。)

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

谢谢!

4

1 回答 1

7

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

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

于 2013-06-07T17:32:09.917 回答