c++ - 正在运行的线程中是否可以使用 QThread::quit

标签 c++ multithreading qt thread-safety qthread

所以我有以下情况:

我有一个运行事件循环的 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/

相关文章:

c++ - 使用 no-angle 和 -no-opengl 编译 Qt 时会发生什么?

qt - 如何在 Qt Creator 中为按钮定义 OnClick 事件处理程序?

C++ XML 解析器(速度,访问 DOM 树)

C++ 频繁暂停和重新启动线程的最佳方法是什么?

linux - QApplication 之后的清理

Python:线程什么时候终止?显然不是(立即)返回

c++ - 您将如何读取 GPU 的前端缓冲区以获取屏幕?

c++ - 为什么这个 C++ 代码在每一行之后打印一个?

c++ - 堆栈基础

mysql - 静态构建 Qt 时找不到 libmysql.dll