在我的代码中,工作线程向gui线程发出信号。信号和插槽通过Qt :: BlockingQueuedConnection连接。
在closeEvent
应用程序期间尝试停止工作线程时,然后才完成事件。
它调用工作线程的功能:
void stop() {
_isFinished = true;
wait();
}
工作线程轮流检查_isFinished
条件,如果没有设置,则发出信号。
对以下情况进行成像
The worker Gui Thread
================= =================
if (!_isFinished) -----------------
----------------- _isFinished = true;
----------------- wait();
emit mySignal(); -----------------
显然,两个线程都会被锁定 - 死锁。
如果我添加一个互斥锁,那么你可以找到另一个死锁情况。当工作人员锁定互斥锁时,gui线程将被阻塞。结果发出的信号将锁定工人。
我该如何处理?
答案 0 :(得分:1)
这就是我看到的情况。
在主线程中,您无需等待工人退出。相反,您的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;
}
这样可以避免死锁。
答案 1 :(得分:0)
在 gui 线程中,您可以使用 QEventLoop 进行等待。看起来像这样:
void stop() {
QEventLoop eventloop;
connect(&theWorkerThread, &QThread::finished, &eventloop, QEventLoop::quit);
_isFinished = true;
eventloop.exe();
}