QT 线程同步 阻塞方式 死锁

前言

针对QT线程同步问题学习:主要QWaitCondition QMutex常用两种进行查阅资料学习。

一、QWaitCondition:

执行过程:主线程获取锁,condition 阻塞进入等待,接着释放锁;另一线程马上获取锁,唤醒condition,释放 锁;

waitCondition适用于需要根据条件判断线程的休眠与否的同步方式。一次可以有选择的让多个线程”同时执行”、”同时休眠”或”随机挑一个线程执行或休眠”,相较mutex方式来说灵活很多

 可以使用下面代码来很清楚的看到上锁解锁 的过程:

#include "widget.h"
#include <QApplication>


#include <QApplication>
#include <QWaitCondition>
#include <QThread>
#include<QTime>
#include<QDebug>
#include <QMutex>

const int DataSize = 1; //任务数
QList<int> taskList;//任务列表
QWaitCondition conditon;
QMutex mutex;
//发布任务的线程
class taskThread : public QThread
{
protected:
    void run()
    {
        QTime ttTime = QTime::currentTime();
        for (int i = 0; i < DataSize; ++i)
        {
            qDebug() <<"-----------------------------";
            mutex.lock();
            qDebug() <<"线程1上锁";
            taskList << i; //
            qDebug() <<"发布任务";
            conditon.wait(&mutex); //等待任务执行结束
            /*注意这一过程中隐藏了  mutex.lock();
                                conditon.wait();
                                mutex.unlock();    */
            qDebug() <<"任务结束";

            mutex.unlock();
            qDebug() <<"线程1解锁";
        }
        qDebug() <<"用时:"<< ttTime.msecsTo(QTime::currentTime()) ;
    }
};
//执行任务的现场
class execThread : public QThread
{
protected:
    void run()
    {
        while (1)
        {
            if(taskList.count() > 0)
            {
                int i = taskList.first();
                qDebug() <<"任务执行中:" ;
                taskList.removeAt(0);

                mutex.lock(); // 注意:唤醒前需要上锁,否则可能被发布任务线程的taskThread,再次上锁,导致死锁
                qDebug() <<"线程2上锁";
                conditon.wakeAll();
                mutex.unlock();
                qDebug() <<"线程2解锁";
            }
            else
            {
                msleep(1);
            }
        }
    }
};

int main(int argc, char *argv[])
{
    taskThread taskT;
    execThread execT;
    taskT.start();
    execT.start();
    taskT.wait();
    execT.wait();
    QApplication a(argc, argv);
    return a.exec();
}

结果显示:

 

二、QMutex

mutex适用于简单的线程同步,即各线程按照一定的条件顺序执行,且一次仅有一个线程活跃,其余线程休眠。QMutexLocker是QMutex的优化版

void ThreadOne_Run::run()
{
    mutex.lock();
    for(int index=0;index<8;index++)
    {
        qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<"ThreadOne_Run子线程ID "<<QThread::currentThread()<<"Add="<<Add;
        Add++;
    }
    mutex.unlock();
}

/*************************子线程2**************************************/
ThreadTwo_movetoThr::ThreadTwo_movetoThr(QObject *parent) : QObject(parent)
{
}

void ThreadTwo_movetoThr::slot_dealTask()
{
    QMutexLocker locker(&mutex);
    for(int index=0;index<8;index++)
    {
        qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<"ThreadTwo_movetoThr子线程ID "<<QThread::currentThread()<<"Add="<<Add;
        Add++;
    }
}

三、死锁

待更新

四、鸣谢

参考博客:

QWaitCondition 的正确使用方法_flyoxs的博客-CSDN博客_qwaitcondition

Qt线程间同步,QWaitCondition和QMutex两种方式_架相的博客-CSDN博客_qt线程同步的方法

 Qt 线程同步(QMutex、QWaitCondition、QSemaphore)_福州-司马懿的博客-CSDN博客

 QT线程QMutex和 QWaitCondition 结合使用的例子_hss2799的博客-CSDN博客


版权声明:本文为sinat_20962951原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。