首页 > 解决方案 > QThread::quit 是否可以在正在运行的线程中使用

问题描述

所以我有以下情况:

我有一个运行事件循环的 QThread(即没有自定义运行函数)。为了停止线程,我向该线程中的工作人员发送了一个信号。然后该工作人员进行清理等,并在某些时候完成并退出线程。

我现在面临的问题是:如果我调用工人停止方法然后立即等待线程完成它永远不会这样做,因为工人完成信号没有得到处理。代码:

class Worker {
signals:
    void done();

public slots:
    void stop() {
        //dummy code to illustrate what happens here:
        QTimer::singleShot(3000, this, &Worker::done);
    }
};

// in the main thread
auto thread = new QThread();
auto worker = new Worker();
worker->moveToThread(thread);
connect(worker, &Worker::done, thread, &QThread::quit); //implicitly a queued connection

// ...

QMetaObject::invokeMethod(worker, "stop", Qt::QueuedConnection);
thread->wait(); //blocks here forever, because the connect is queued

现在原因问题很明显 - 因为我在主线程上阻塞,所以永远不能调用插槽(因为排队连接),因此永远不会调用退出。但是,如果我只是直接从工作人员调用QThread::quit(or )(或使用 a ),那么就没有问题了,因为不再需要主线程的 eventloop 来处理事件。QThread::exitDirectConnection

所以这里的实际问题是:这是否允许?我可以QThread::quit从实际线程中调用吗?或者这会产生竞争条件、死锁和其他类似的问题。文档没有将该方法标记为线程安全 - 但由 QThread 管理的线程可能是一个异常。

标签: c++multithreadingqtthread-safetyqthread

解决方案


如果查看src/corelib/thread/qthread.cppQt 源文件夹中的文件,可以看到quit()是如何实现的:

void QThread::quit()
{ exit(); }

.... 并且QThread::exit()绝对打算从线程本身中调用。所以答案是肯定的,可以quit()从 QThread 的线程中调用(尽管直接调用可能更常见一些QThread::exit())。


推荐阅读