刻骨铭心 的QT 线程死锁

直接上代码,直观明了。总结在此,避免再次踩坑。

//1.锁的作用域过大引起的死锁
如果异常根源处的大括号不启用,调用stop()时,锁一直被占用,
因为m_bRuning一直为true,死循环。此处等待m_bRuning为false;
而根源相关处等待锁释放,才能将m_bruning置为false;
一处等待m_bruning置为false;才能释放锁;一处等待锁释放,才能将
m_bruning置为false; 相互等待,最终死锁!

void StationBThread::stop()
{
    m_pCtrl->setQuitFlag(m_id,true);
    //{                                                       异常根源
       QMutexLocker locker(&m_Mutex);
        m_bStop = true;
    //}                                                      异常根源
    int nStep = 10;
    int count = (60 * 1000) / nStep;
    while (m_bRuning)
    {
        QThread::msleep(10);
        if (--count <= 0)
            break;
    }
}

void StationBThread::run()
{
    m_bRuning = true;
    while (true)
    {
        while (!m_pCtrl->IsStationHasTask(m_id))
        {
            QThread::msleep(2);
            QApplication::processEvents();
            {
                QMutexLocker locker(&m_Mutex); 根源相关
                if(m_bStop)
                    break;
            }
        }
        {
            QMutexLocker locker(&m_Mutex);
            if (m_bStop)                                                 根源相关
                break;
        }
        m_pCtrl->ResetStationTask(m_id);

        if (m_pCtrl->HasStuff(m_id))
        {
                                     // Do some thing......
                                     goto rest;
        }
        else
        {
                                      // Do some thing......
                          goto rest;
        }
    rest:
        {
                m_pCtrl->asyncWait(10);
                QMutexLocker locker(&m_Mutex);  根源相关
                if (m_bStop)
            break;
        }
    }
    m_bRuning = false;
    m_bStop = false;
}

//2.锁的嵌套导致死锁
此处比较简单,就不做过多分析,一般锁只作用于最基础需要保护的内存数据
Func A()
{
   QMutexLocker locker(&m_Mutex); //已占有锁
  Func B();
}
Func B()
{
   QMutexLocker locker(&m_Mutex); //等待锁
   //Do some thing......
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值