c++ - 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::exit
DirectConnection
所以这里的实际问题是:这是否允许?我可以QThread::quit
从实际线程中调用吗?或者这会产生竞争条件、死锁和其他类似的问题。文档没有将该方法标记为线程安全 - 但由 QThread 管理的线程可能是一个异常。
解决方案
如果查看src/corelib/thread/qthread.cpp
Qt 源文件夹中的文件,可以看到quit()
是如何实现的:
void QThread::quit()
{ exit(); }
.... 并且QThread::exit()
绝对打算从线程本身中调用。所以答案是肯定的,可以quit()
从 QThread 的线程中调用(尽管直接调用可能更常见一些QThread::exit()
)。
推荐阅读
- .net - 为什么Jenkins在构建后无法注册dll?
- java - AspectJ AOP LTW 不适用于 javaagent 的动态加载
- spring-boot - 如何使用 Spring-Boot 配置 Eclipse-RCP
- java - 在char数组java中查找一个单词
- asp.net-mvc - 如何在 ASP.NET MVC 中为这种场景选择合适的过滤器?
- ios - 透明状态下的大 UINavigationBar 无法返回默认状态
- java - JFrame 之间的交互
- php - mysqli_result 似乎没有实现 Iterator 接口
- tensorflow - 在强化学习中绑定神经网络输出的最佳方法
- r - 并排方框绘图中的错误