c++ - 正确终止一个 QThread

标签 c++ qt qthread

我有一个在后台进行图像采集的工作类。

void acq::run ()
{
    while (m_started)
    {
        blocking_call();
    }
    emit workFinished();
}

void acq::start ()
{
    m_started = true;
    run();
}

void acq::stop ()
{
    m_started = false;
}

开始(); stop () 是槽,workFinished 是信号。

所以在我的 UI 类中,我启动了 worker 并将信号连接到插槽:

m_thread = new QThread;
m_worker = new acq();

m_worker->moveToThread(m_thread);

// When the thread starts, then start the acquisition.
connect(m_thread, SIGNAL (started ()), m_worker, SLOT (start ()));

// When the worker has finished, then close the thread
connect(m_worker, SIGNAL(workFinished()), m_thread, SLOT(quit()));

m_thread->start();

至此,我实现了槽,closeEvent

void UIClass::closeEvent (QCloseEvent *event)
{
    m_worker->stop(); // tell the worker to close
    m_thread->wait(); // wait until the m_thread.quit() function is called
    event->accept(); // quit the window
}

不幸的是,m_thread->wait() 正在阻塞。即使发出信号 quit()

谢谢

编辑:

我添加了这两个连接:

connect(m_worker, SIGNAL(workFinished()), m_worker, SLOT(deleteLater()));
connect(m_thread, SIGNAL(finished()), m_thread, SLOT(deleteLater()));

和一个 Qdebug 到 acq::~acq()

打印的消息证明调用了停止,发出了 workFinished,发出了 deleteLater()。

最佳答案

不同线程上的对象之间的正常信号/槽连接需要接收者对象的线程运行事件循环。

您的接收器线程理论上确实运行了它的事件循环,但事件循环正忙于执行 start() 槽,因为 run() 永远不会返回。

您需要取消阻塞接收器事件循环或使用 Qt::DirectConnection 调用停止槽。

在执行后者时,您需要注意槽现在在发送方线程的上下文中被调用,并且您需要保护 m_started 免受并发访问。

除了使用您自己的标志,您还可以使用 QThread::requestInterruption()QThread::isInterruptionRequested()

关于c++ - 正确终止一个 QThread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41588742/

相关文章:

c# - 编码(marshal)结构后跟固定大小的数据

c++ - 如何将 lambda 函数排队到 Qt 的事件循环中?

c++ - 识别图像文件格式

c++ - 另一个奇怪的编译器错误 : calling a templated function which gives undefined referenes

c++ - 元编程中有哪些数学运算符可用

c++ - Qt 布局间隔大小

QtCreator : QML Debugger, 连接被拒绝 - 关闭 QML 调试器?

qt - QMainWindow 设置 frameSize

multithreading - 当调用 QWebFrame 的评估Javascript方法时,QT 应用程序崩溃

c++ - 如何在具有 OpenMP 功能的 QThread 中强制使用多核