Qt多线程同步,使用互斥量。
-
实现
- 分别创建生产者类、消费者类,继承QThread,重写run()。
- 主函数创建生产者类实例、消费者类实例;使用start()启动线程,里面会调用run();使用wait()等待线程结束。
-
生产者类.h文件,如下。
cpp
#ifndef PRODUCERTHREAD_H
#define PRODUCERTHREAD_H
#include <QThread>
#include <QDebug>
#include <QQueue>
#include <QMutex>
class ProducerThread : public QThread
{
public:
ProducerThread();
protected:
void run(); //重写run()
};
#endif // PRODUCERTHREAD_H
- 生产者类.cpp文件,如下。
cpp
#include "producerthread.h"
QMutex mutex; //互斥量,用于保护共享资源
QQueue<int> buffer; //缓冲区, 用于存放数据
const int BufferSize = 10; //缓冲区大小
const int DataSize = 20; //每个线程数据量
ProducerThread::ProducerThread() {}
void ProducerThread::run()
{
int i=0;
while(true)
{
mutex.lock();
if(buffer.size()<BufferSize) //缓冲区不满时
{
buffer.enqueue(i);
qDebug()<< "Producer ID:" << QThread::currentThreadId() << " Produced: " << i ;
}
mutex.unlock();
if(++i==DataSize) return; //生产DataSize个数据
msleep(100); //模拟生产过程
}
}
- 消费者类.h文件,如下。
cpp
#ifndef CONSUMERTHREAD_H
#define CONSUMERTHREAD_H
#include <QThread>
class ConsumerThread : public QThread
{
public:
ConsumerThread();
protected:
void run();
};
#endif // CONSUMERTHREAD_H
- 消费者类.cpp文件,如下。
cpp
#include "consumerthread.h"
#include "producerthread.h"
extern QMutex mutex; //引用互斥量
extern QQueue<int> buffer; //引用缓冲区
extern const int DataSize = 20; //引用每个线程数据量
ConsumerThread::ConsumerThread(){}
void ConsumerThread::run()
{
int i=0;
while(true)
{
mutex.lock();
if(!buffer.isEmpty()) //缓冲区不空时
qDebug()<< "Consumer ID:" << QThread::currentThreadId() << " Consumed: " << buffer.dequeue();
mutex.unlock();
if(++i==DataSize) return; //消费DataSize个数据
msleep(200); //模拟消费过程
}
}
- main.cpp,如下。
cpp
#include "mainwindow.h"
#include <QApplication>
#include"consumerthread.h"
#include"producerthread.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//MainWindow w;
//w.show();
ProducerThread producer1;
ProducerThread producer2;
ConsumerThread consumer1;
ConsumerThread consumer2;
producer1.start();
producer2.start();
consumer1.start();
consumer2.start();
producer1.wait();
producer2.wait();
consumer1.wait();
consumer2.wait();
return a.exec();
}