Qt 生产者消费者模型

基于QT实现的生产者消费者模型
不足之处请留言指出

//global.h
#ifndef GLOBAL_H
#define GLOBAL_H
 
#include <QMutex>
#include <QWaitCondition>
#include <QIODevice>
 
extern QMutex         g_mutex;
extern QWaitCondition g_bufferFull;
extern QWaitCondition g_bufferEmpty;
 

#endif// GLOBAL_H

//global.cpp

#include <QtCore>
#include "global.h"
 
QMutex         g_mutex;
QWaitCondition g_bufferFull;
QWaitCondition g_bufferEmpty;
 
 


//Resource.h
#ifndef RESOURCE_H
#define RESOURCE_H
 
#include <QObject>
 
class Resource : public QObject
{
    Q_OBJECT
public:
    explicit Resource(QObject *pParent = NULL);
 
    void push(QByteArray byte);
 
    void popup();
 
signals:
    void dataChanged(const QByteArray&);
 
public slots:
 
private:
    int  m_index;
    bool m_flag;
};
 
#endif // RESOURCE_H
 
//Resource.cpp
#include <QtCore>
#include "global.h"
#include "Resource.h"
 
Resource::Resource(QObject *pParent)
    : QObject(pParent),
      m_index(0),
      m_flag(false)
{
}
 
void Resource::push(QByteArray byte)
{
    QMutexLocker locker(&g_mutex);
    while (m_flag == true)
    {
        g_bufferFull.wait(&g_mutex);
    }
    qDebug()<<"Producer:"<<++m_index;
    m_flag = true;
    g_bufferEmpty.wakeAll();
}
 
void Resource::popup()
{
    QMutexLocker locker(&g_mutex);
    while (m_flag == false)
    {
        g_bufferEmpty.wait(&g_mutex);
    }
    qDebug()<<"   Consumer:"<<m_index;
    m_flag = false;
    g_bufferFull.wakeAll();
}
 
 
 

//Producer.h
#ifndef PRODUCER_H
#define PRODUCER_H
 
#include <QThread>
#include "Resource.h"
 
class Producer : public QThread
{
    Q_OBJECT
public:
    explicit Producer(Resource &res, QObject *parent = 0);
 
protected:
    void run();
 
signals:
 
public slots:
 
private:
    Resource &m_res;
};
 
#endif // PRODUCER_H
 

//Producer.cpp
#include <QtCore>
#include "global.h"
#include "Producer.h"
 
Producer::Producer(Resource &res, QObject *parent)
    : QThread(parent),
    m_res(res)
{
}
 
void Producer::run()
{
//    while (true)
    for (int i=0; i<30; ++i)
    {
        /****************** 测试数据 ******************/
        QByteArray byte;
        QDataStream out(&byte, QIODevice::WriteOnly);
        QString time = QTime::currentTime().toString("hh:mm:ss");
        out<<time;
        /****************** 测试数据 ******************/
 
        m_res.push(byte);
        usleep(500);
    }
}
 

//Consumer.h
#ifndef CONSUMER_H
#define CONSUMER_H
 
#include <QThread>
#include "Resource.h"
 
class Consumer : public QThread
{
    Q_OBJECT
public:
    explicit Consumer(Resource &res, QObject *parent = 0);
protected:
    void run();
 
signals:
 
public slots:
 
private:
    Resource &m_res;
 
};
 
#endif // CONSUMER_H
 

//Consumer.cpp
#include <QtCore>
#include "Consumer.h"
 
Consumer::Consumer(Resource& res, QObject *parent)
    : QThread(parent),
      m_res(res)
{
}
 
void Consumer::run()
{
    while (true)
    {
        m_res.popup();
    }
}
 
//main.cpp
#include <QtCore>
#include "Resource.h"
#include "Producer.h"
#include "Consumer.h"
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
    Resource res;
 
    //1
    Producer p1(res);
    p1.setObjectName("t1");
    p1.start();
 
    Consumer c1(res);
    c1.setObjectName("c1");
    c1.start();
 
 
    //2
    Producer p2(res);
    p2.setObjectName("t2");
    p2.start();
 
    Consumer c2(res);
    c2.setObjectName("c2");
    c2.start();
 
 
    //3
    Producer p3(res);
    p3.setObjectName("t3");
    p3.start();
 
    Consumer c3(res);
    c3.setObjectName("c3");
    c3.start();
 
    return a.exec();
}
 


                
Qt中,可以使用QSemaphore和QMutex来实现生产者消费者队列。具体实现步骤如下: 1.定义一个缓冲区类,该类包含一个缓冲区数组和两个指针,分别指向缓冲区的头和尾。缓冲区类还包含一个QSemaphore对象和一个QMutex对象,用于实现线程同步。 2.在缓冲区类中定义两个方法:一个用于向缓冲区中添加数据的生产者方法,另一个用于从缓冲区中取出数据的消费者方法。这两个方法都使用QSemaphore对象来控制缓冲区的大小。 3.在主函数中创建一个缓冲区对象和两个线程对象,一个用于生产者,另一个用于消费者。将缓冲区对象传递给这两个线程对象。 4.在生产者线程中,调用缓冲区对象的生产者方法,向缓冲区中添加数据。 5.在消费者线程中,调用缓冲区对象的消费者方法,从缓冲区中取出数据。 下面是一个简单的Qt生产者消费者队列的示例代码: ```cpp #include <QCoreApplication> #include <QThread> #include <QDebug> #include <QSemaphore> #include <QMutex> const int BufferSize = 10; class Buffer { public: Buffer() { m_head = 0; m_tail = 0; m_freeBytes = BufferSize; m_usedBytes = 0; } void produce(int data) { m_freeSpace.acquire(); m_mutex.lock(); m_buffer[m_tail] = data; m_tail = (m_tail + 1) % BufferSize; m_freeBytes--; m_usedBytes++; m_mutex.unlock(); m_usedSpace.release(); } int consume() { m_usedSpace.acquire(); m_mutex.lock(); int data = m_buffer[m_head]; m_head = (m_head + 1) % BufferSize; m_freeBytes++; m_usedBytes--; m_mutex.unlock(); m_freeSpace.release(); return data; } private: int m_buffer[BufferSize]; int m_head; int m_tail; int m_freeBytes; int m_usedBytes; QSemaphore m_freeSpace{BufferSize}; QSemaphore m_usedSpace{0}; QMutex m_mutex; }; class Producer : public QThread { public: Producer(Buffer* buffer) { m_buffer = buffer; } void run() override { for (int i = 0; i < 100; i++) { m_buffer->produce(i); qDebug() << "Produced:" << i; msleep(10); } } private: Buffer* m_buffer; }; class Consumer : public QThread { public: Consumer(Buffer* buffer) { m_buffer = buffer; } void run() override { for (int i = 0; i < 100; i++) { int data = m_buffer->consume(); qDebug() << "Consumed:" << data; msleep(50); } } private: Buffer* m_buffer; }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Buffer buffer; Producer producer(&buffer); Consumer consumer(&buffer); producer.start(); consumer.start(); producer.wait(); consumer.wait(); return a.exec(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞天遇见妞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值