QMutexLocker导致程序卡死

项目中出现一个问题,当使用QMessageBox弹窗后,通讯线程卡住,run()函数中的while(true)循环一直未进入。
这个现象首先猜测弹窗会卡住界面,但是经过添加打印信息,发现主线程中的QTimer定时器仍在正常执行,但是通讯线程while循环中的打印信息却一直未打印,为什么主线程没有卡住,但子线程卡住了,一下子懵了,居然会有这么神奇的事情。
最终通过代码回退对比,发现问题原因竟然出现在QMutexLocker上。

QMutexLocker上锁和解锁的原理:在该局部变量被创建的时候上锁,当所在函数运行完毕后该QMutexLocker局部变量在栈中销毁掉,也就相对应的解锁了

下面展示一些 代码,Controller为通讯线程类。

void Controller::slotReadConfirmed(const QByteArray &data)
{
    QMutexLocker locker(&readMutex);
    // check hash table to decide where to send the received data.
    BaseClientWidget *clientUI = nullptr;
    if(m_ui_hash.contains(m_current_ui)){
        clientUI = m_ui_hash.value(m_current_ui);
        m_readNextPackage = true;   // break the reading block after handle data. do not modify m_current_ui before you read the current ui.
        if(data.isEmpty()){
            qDebug() << "Controller:: recv data length = 0";
            return;
        }
        clientUI->handleData(data);
    }else{
        m_readNextPackage = true;   // doesn't contains current ui
    }
}

QMutexLocker 的作用域是{}内部,所以slotReadConfirmed()函数中对handleData()也进行了加锁,执行虚函数handleData时并没有解锁,而handledata是在窗口类中执行的,而弹窗刚好是在handledata中弹出,所以handledata阻塞,那么slotReadConfirmed也被阻塞,即通讯线程被阻塞,所以run函数中的while(true)循环不再进入。
解决方案:不适用QMutexlocker,使用lock()和unlock()函数即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值