在我的代码中,工作线程向 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/