所以我有以下情况:
我有一个运行事件循环的 QThread(即没有自定义运行函数)。为了停止线程,我向该线程中的工作人员发送了一个信号。然后这个工作人员进行清理等工作,并在某个时候完成并退出线程。
我现在面临的问题是:如果我调用 workers stop 方法然后立即等待线程完成,它永远不会这样做,因为 workers 完成信号没有得到处理。代码:
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
现在问题很明显了——因为我阻塞在主线程上,槽永远不会被调用(因为排队的连接),因此退出永远不会被调用。但是,如果我直接从工作人员(或使用 DirectConnection
)直接调用 QThread::quit
(或 QThread::exit
),那么不再是问题,因为不再需要主线程的事件循环来处理事件。
所以这里的实际问题是:这允许吗?我可以从实际线程中调用 QThread::quit
吗?或者这会造成竞争条件、死锁和其他类似问题。文档没有将该方法标记为线程安全的 - 但由 QThread 管理的线程可能是一个异常(exception)。
最佳答案
如果您查看 Qt 源文件夹中的文件 src/corelib/thread/qthread.cpp
,您可以看到 quit()
是如何实现的:
void QThread::quit()
{ exit(); }
.... 和QThread::exit()
绝对是为了从线程本身内部调用。所以答案是肯定的,从 QThread 的线程中调用 quit()
很好(尽管调用 QThread::exit()
可能更常见一些)直接代替)。
关于c++ - 正在运行的线程中是否可以使用 QThread::quit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50841645/