在我的代码中,工作线程向gui线程发出一个信号。信号和插槽通过Qt :: BlockingQueuedConnection连接。
In my code a worker thread emits a signal to gui thread. Signal and Slot are connected via Qt::BlockingQueuedConnection.
当 closeEvent 应用程序尝试停止工作
When during thecloseEvent application is trying to stop the worker thread and only then finishes the event.
它调用工作线程的函数:
It calls the function of worker thread:
void stop() { _isFinished = true; wait(); }工作线程检查 _isFinished <
The worker thread in its turn checks _isFinished condition and if it is not set up then emit the signal.
成像以下情况
The worker Gui Thread ================= ================= if (!_isFinished) ----------------- ----------------- _isFinished = true; ----------------- wait(); emit mySignal(); -----------------显然,将被锁定 - 死锁。
Evidently, both threads would be locked - deadlock.
如果我添加一个互斥,那么你可以找到另一个死锁情况。当工作者锁定互斥量和gui线程将被阻塞。结果发出的信号将锁定工人。
If I add a mutex then you can find another deadlock situation. When the worker locks the mutex and the gui thread would be blocked. As a result the emitted signal will lock the worker.
我该如何处理?
推荐答案这是我看到的情况。
主线程你不需要等待工人退出。您的 closeEvent 应该看起来像这样:
In your main thread you do not need to wait for worker to quit. Instead your closeEvent should look like this:
if (workerThread->isRunning()) { workerThread->stop(); event->ignore(); }要使这项工作,你还需要关闭主窗口,完成:
To make this work, you also need to close main window, when worker thread finishes:
connect(workerThread, SIGNAL(finished()), SLOT(close()));最后,使用 _isFinished 所有其他变量在工作线程)应该发生在工作线程。您可以用一个简单的技巧实现它:
Finally, all manipulations with _isFinished (and all other variables in worker thread) should occur in worker thread. You can achieve it with a simple trick:
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; }这样可以避免死锁。
更多推荐
qt信号时隙多线程死锁
发布评论