qt信号时隙多线程死锁 [英] qt signal-slot multithreading deadlocks

查看:360
本文介绍了qt信号时隙多线程死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的代码中,工作线程向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信号时隙多线程死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆