业务类:
#pragma once
#include "qobject.h"
#include "qmythread.h"
class QBusiness :
public QObject
{
Q_OBJECT
public:
explicit QBusiness();
~QBusiness();
void startBusiness();
void stopBusiness();
private slots:
void onthreadA_started();
void onthreadA_finished();
void onthreadB_started();
void onthreadB_finished();
void onthreadB_newValue(int *data, int count, int bufNo);
private:
QThreadDAQ threadProducer;
QThreadShow threadConsumer;
};
业务类实现:
#include "QBusiness.h"
#include <QDebug>
QBusiness::QBusiness()
{
connect(&threadProducer, SIGNAL(started()), this, SLOT(onthreadA_started()));
connect(&threadProducer, SIGNAL(finished()), this, SLOT(onthreadA_finished()));
connect(&threadConsumer, SIGNAL(started()), this, SLOT(onthreadB_started()));
connect(&threadConsumer, SIGNAL(finished()), this, SLOT(onthreadB_finished()));
connect(&threadConsumer, SIGNAL(newValue(int*, int, int)),
this, SLOT(onthreadB_newValue(int*, int, int)));
}
QBusiness::~QBusiness()
{
stopBusiness();
}
void QBusiness::startBusiness()
{
threadConsumer.start();
threadProducer.start();
}
void QBusiness::stopBusiness()
{
if (threadProducer.isRunning())
{
threadProducer.terminate();//结束线程的run()函数执行
threadProducer.wait();//
}
if (threadConsumer.isRunning())
{
threadConsumer.terminate(); //因为threadB可能处于等待状态,所以用terminate强制结束
threadConsumer.wait();//
}
}
void QBusiness::onthreadA_started()
{
qDebug() << "Thread Producer status: started";
}
void QBusiness::onthreadA_finished()
{
qDebug() << "Thread Producer status: finished";
}
void QBusiness::onthreadB_started()
{
qDebug() << "Thread Consumer status: started";
}
void QBusiness::onthreadB_finished()
{
qDebug() << "Thread Consumer status: finished";
}
void QBusiness::onthreadB_newValue(int *data, int count, int bufNo)
{
//读取threadConsumer 传递的缓冲区的数据
QString str = QString("number %1 buffer:").arg(bufNo);
for (int i = 0; i < count; i++)
{
str = str + QString("%1, ").arg(*data);
data++;
}
str = str + '\n';
qDebug() << str;
}
生产者-消费者模型:
#pragma once
#include <QObject>
#include <QThread>
class QThreadDAQ : public QThread
{
Q_OBJECT
private:
bool m_stop = false; //停止线程
protected:
void run() Q_DECL_OVERRIDE;
public:
QThreadDAQ();
void stopThread();
};
class QThreadShow : public QThread
{
Q_OBJECT
private:
bool m_stop = false; //停止线程
protected:
void run() Q_DECL_OVERRIDE;
public:
QThreadShow();
void stopThread();
signals:
void newValue(int *data, int count, int seq);
};
#include "qmythread.h"
#include <QSemaphore>
const int BufferSize = 8;
int buffer1[BufferSize];
int buffer2[BufferSize];
int curBuf = 1; //当前正在写入的Buffer
int bufNo = 0; //采集的缓冲区序号
quint8 counter = 0;//数据生成器
QSemaphore emptyBufs(2);//信号量:空的缓冲区个数,初始资源个数为2
QSemaphore fullBufs; //满的缓冲区个数,初始资源为0
void QThreadDAQ::run()
{
m_stop = false;//启动线程时令m_stop=false
bufNo = 0;//缓冲区序号
curBuf = 1; //当前写入使用的缓冲区
counter = 0;//数据生成器
int n = emptyBufs.available();
if (n < 2) //保证 线程启动时emptyBufs.available==2
emptyBufs.release(2 - n);
while (!m_stop)//循环主体
{
emptyBufs.acquire();//获取一个空的缓冲区
for (int i = 0; i < BufferSize; i++) //产生一个缓冲区的数据
{
if (curBuf == 1)
buffer1[i] = counter; //向缓冲区写入数据
else
buffer2[i] = counter;
counter++; //模拟数据采集卡产生数据
msleep(50); //每50ms产生一个数
}
bufNo++;//缓冲区序号
if (curBuf == 1) // 切换当前写入缓冲区
curBuf = 2;
else
curBuf = 1;
fullBufs.release(); //有了一个满的缓冲区,available==1
}
quit();
}
QThreadDAQ::QThreadDAQ()
{
}
void QThreadDAQ::stopThread()
{
m_stop = true;
}
void QThreadShow::run()
{
m_stop = false;//启动线程时令m_stop=false
int n = fullBufs.available();
if (n > 0)
fullBufs.acquire(n); //将fullBufs可用资源个数初始化为0
while (!m_stop)//循环主体
{
fullBufs.acquire(); //等待有缓冲区满,当fullBufs.available==0阻塞
int bufferData[BufferSize];
int seq = bufNo;
if (curBuf == 1) //当前在写入的缓冲区是1,那么满的缓冲区是2
for (int i = 0; i < BufferSize; i++)
bufferData[i] = buffer2[i]; //快速拷贝缓冲区数据
else
for (int i = 0; i < BufferSize; i++)
bufferData[i] = buffer1[i];
emptyBufs.release();//释放一个空缓冲区
emit newValue(bufferData, BufferSize, seq);//给主线程传递数据
}
quit();
}
QThreadShow::QThreadShow()
{
}
void QThreadShow::stopThread()
{
m_stop = true;
}
main函数调用:
#include <QtCore/QCoreApplication>
#include "QBusiness.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QBusiness qb;
qb.startBusiness();
return a.exec();
}