c++ - QThread - 如何停止 worker ?

标签 c++ qt

我读到我应该使用 worker 对象并通过 moveToThread 将其移动到线程,而不是直接从 QThread 继承。但是我找不到如何在我的对象 worker 中停止循环的解决方案。例如我有测试循环:

void CollectionWorker::doWork()
{
    for (int i = 0; i < 10; ++i) {
        sleep(1);
        emit ping(i);
    }
}

现在我将这个对象移动到线程:

worker->moveToThread(mTh); 

这工作正常。但是当我调用 mTh.quit() 时,线程正在等待,直到 doWork 中的循环结束。当我直接从 QThread 继承时,然后在每个循环上我可以检查线程状态并在 thred 完成时中断循环,但不知道如何在 worker 对象中执行此操作。我可以只在工作对象中创建一些标志并将其从主线程切换吗?或者我可以找到线程所有者并检查它的状态吗?或者在启动线程之前更好,在工作对象中设置线程指针然后检查状态?最好的线程安全解决方案是什么?

问候

最佳答案

在线程对象上调用 quit() 或 exit() 将简单地结束线程的事件循环(如果有线程正在运行)。但是正如您正确指出的那样,最初的问题仍然存在。如果 worker 函数已经被事件循环执行过并且是一个具有 forever 构造的长时间运行的函数怎么办。对 quit() 或 exit() 的调用只会等待辅助函数返回。

除了使调用者可以使用公共(public)函数(这将更改内部标志)之外,还可以建议几种方法。

  • 在您的工作类中提供终止信号和插槽。内容如下。

    signals:
        void signalTermination();
    public slots:
        void setTerminationFlag();
    private:
        QMutex mutex;
        bool terminationRequested;

你的插槽看起来像什么。

void setTerminationFlag()
{
    QMutexLocker locker(&mutex);
    terminationRequested = true;
}

然后您可以在永远循环的每次迭代中检查 doWork 函数中的变量。

mutex.lock();
if(terminationRequested)
{
    //break from loop and effectively doWork function
}
mutex.unlock();

使用信号和槽而不是普通成员函数的原因之一是,如果您的辅助函数在同步代码块内执行一些长时间运行的任务,则公共(public)函数将保持阻塞状态,直到它获得对同步对象的访问权限。如果您的公共(public)终止方法的调用线程是 UI 线程,这可能会产生不利影响。

  • 如果您使用的是 Qt 5.2 或更高版本,这是另一种更简洁的方法

使用 QThread 的 requestInterruption() 方法。此方法在线程对象中设置一个咨询标志,您可以通过 doWork() 函数中的 isInterruptionRequested() 函数调用来检查该标志。请参阅 QThread::isInterruptionRequested 中给出的以下代码片段文档。

void long_task() {
    forever {
        if ( QThread::currentThread()->isInterruptionRequested() ) {
            return;
        }
    }
}

也可以在这里直接调用quit()结束线程的事件循环。

关于c++ - QThread - 如何停止 worker ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15269051/

相关文章:

c++ - 将 Mat 转换为 QPixmap

linux - Qt 5.5 未绑定(bind)到端口

c++ - 为什么这段代码可以在 VS 上运行,但不能在 gcc/g++ 上运行?

c++ - 为什么QQuickWindow-> close()从rootObjects中删除对象?

c++ - QT 5.7 QPainter 线条对齐

c++ - 调用堆栈图

c++ - 相当于 boost::shared_array 的 Qt 智能指针?

c++ - HippoMocks - 模拟一个返回 unique_ptr 的函数

c++ - Boost 堆元素句柄比较和 MSVC 迭代器调试工具

c++ - 如何使用 C 预处理器生成可变大小(取决于操作系统)的十六进制文字?