c++ - qt信号槽多线程死锁

标签 c++ multithreading qt

在我的代码中,工作线程向 gui 线程发出信号。 Signal 和 Slot 通过 Qt::BlockingQueuedConnection 连接。

closeEvent 期间,应用程序试图停止工作线程,然后才结束事件。

它调用工作线程的函数:

void stop() {
  _isFinished = true;
  wait();
}

工作线程依次检查 _isFinished 条件,如果未设置则发出信号。

想象一下下面的情况

The worker            Gui Thread 
=================     =================
if (!_isFinished)     -----------------
-----------------     _isFinished = true;
-----------------     wait();
emit mySignal();      -----------------

显然,两个线程都将被锁定 - 死锁。

如果我添加一个互斥量,那么您会发现另一种死锁情况。当工作人员锁定互斥锁时,gui 线程将被阻塞。结果,发出的信号将锁定工作人员。

我该如何处理?

最佳答案

我是这样看的。

在你的主线程中你不需要等待 worker 退出。相反,您的 closeEvent 应该如下所示:

if (workerThread->isRunning())
{
    workerThread->stop();
    event->ignore();
}

为了让它工作,你还需要在工作线程结束时关闭主窗口:

connect(workerThread, SIGNAL(finished()), SLOT(close()));

最后,所有对 _isFinished 的操作(以及工作线程中的所有其他变量)都应该发生在工作线程中。您可以通过一个简单的技巧实现它:

WorkerThread.h

public:
    void stop();

protected slots:
    void p_stop();

protected:
    QMutex mutex;

WorkerThread.cpp

void WorkerThread::stop()
{
    staticMetaObject.invokeMethod(this, "p_stop", Qt::QueuedConnection);
}

void WorkerThread::p_stop();
{
    QMutexLocker locker(&mutex);
    _isFinished = true;
}

这样可以避免死锁。

关于c++ - qt信号槽多线程死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16741432/

相关文章:

C++ 模板 "class type"错误

C++ - cstyle 结构/类包装相关吗?

c++ - 无法创建 ICaptureGraphBuilder2 的实例

c++ - 如何在其他两个之间设置工具栏

c++ - 只读结构?如何在结构中使用指针?

c++ - 如何在类中声明 static const struct 元素

java - 从线程启动新线程

java - 当线程在 Java 中死亡时 ThreadPoolExecutor 会发生什么

ios - XML 解析器正在阻塞主线程

c++ - 如何序列化QSound?