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、互斥鎖同一時間只能被一條線程使用。本實例中最好在消費者線上也加上互斥鎖,因爲消費者線上也厚對共享列表的操作。