Qt 互斥锁 QMutex 的简单应用
在多线程解决问题中,经常会碰到多个线程操作同一片资源,有些时候用信号量的方式去处理,但有的时候需要用到互斥锁。
互斥锁:说白了就是,资源某个时间只能被一个线程使用。打个比方:家里的微波炉每次只能被一个人使用。
Qt中官网有个关于信号量的示例,http://doc.qt.io/qt-5/qtcore-threads-semaphores-example.html
我们将上面的示例改写,利用互斥锁来实现。
任务要求:
1、两条生产线,只能共用一个数据仓库,同时时间数据仓库只能被一条生产线来使用。
2、一条消费者先,只要数据仓库未空,就取出数据。
输入结果如下:
代码实现:
#include <QtCore>
#include <stdio.h>
#include <stdlib.h>
#include <QDebug>
#include <QList>
#include<QMutex>
const int DataSize = 15;
const int BufferSize = 20;
QList<char> bufferlist; //共享的数据列表
QMutex mutexlock; //互斥锁
// 生产者线程类
class Producer_01 : public QThread
{
public:
void run();
};
void Producer_01::run()
{
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
for (int i = 0; i < DataSize; ++i) {
mutexlock.lock();
char test = "ACGT"[(int)qrand() % 4];
bufferlist.append(test);
qDebug() << QString("producer_01: %1").arg(test);
mutexlock.unlock();
sleep(1);
}
}
class Producer_02 : public QThread
{
public:
void run();
};
void Producer_02::run()
{
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
for (int i = 0; i < DataSize; ++i) {
mutexlock.lock();
char test = "HIJK"[(int)i % 4];
bufferlist.append(test);
qDebug() << QString("producer_02: %1").arg(test);
mutexlock.unlock();
msleep(300);
}
}
// 消费者线程类
class Consumer : public QThread
{
public:
void run();
};
void Consumer::run()
{
while (1)
{
if(bufferlist.isEmpty()==false) //如果数据列表未空,就从头还是取数据
{
msleep(500); //增加延时,表示消费的滞后时间
qDebug() << QString("consumer: %1").arg(bufferlist[0]);
bufferlist.removeAt(0); //删除链表的头
}
}
}
// 主函数
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
Producer_01 producer_01; //创建生产者的线程
Producer_02 producer_02;
Consumer consumer; //创建消费者的线程
producer_01.start(); //线程开启
producer_02.start();
consumer.start();
producer_01.wait();
producer_02.wait();
consumer.wait();
return app.exec();
}
总结:
1、互斥锁相对信号量更好理解和应用。
2、互斥锁同一时间只能被一条线程使用。本实例中最好在消费者线上也加上互斥锁,因为消费者线上也厚对共享列表的操作。