QT 生产者消费者模型

首先感谢下这个博主 我很多都是在他这边借鉴的,下面是他的文章的原链接

https://blog.csdn.net/qq_38318941/article/details/102558351

下面是我对他的线程方面的改动 以及我的一些理解,我才用的是官方推荐的moveToThread的方法来创建多线程的。废话不多说,开始讲解关于生产者消费者模型的搭建。

QT中的生产者消费者模型涉及到很多知识,其中生产者和消费者涉及到多线程问题,还有由于生产者消费者要操作同一块内存的数据所以,这又涉及到队列(QQueue)和信号量(QSemaphore)的综合应用.

这里对需要进行同一块操作的内存进行包装成一个类blockMsgQueue

blockMsgQueue.h文件

#ifndef BLOCKMSGQUEUE_H
#define BLOCKMSGQUEUE_H

#include <QSemaphore>
#include <QMutex>
#include <QQueue>

class blockMsgQueue
{
public:
    blockMsgQueue(const int &maxMsgsNum, const unsigned int &msgSize);
    ~blockMsgQueue();

    void addMsg(const char *msgPack);
    void getMsg(char *msgPack);

private:
    int m_maxMsgsNum;
    unsigned int m_msgSize;
    QSemaphore *m_pFreeMsgs;
    QSemaphore *m_pUsedMsgs;
    QQueue<char *> m_queue;
    QMutex m_mutex;
};
#endif // BLOCKMSGQUEUE_H

blockMsgQueue.c文件

#include "blockMsgQueue.h"

blockmsgqueue::blockMsgQueue(const int &m_maxMsgsNum, const unsigned int &msgSize)
    :m_maxMsgsNum(m_maxMsgsNum),
     m_msgSize(msgSize)
{
    m_pFreeMsgs = new QSemaphore(m_maxMsgsNum);
    m_pUsedMsgs = new QSemaphore(0);

}

blockmsgqueue::~blockmsgqueue()
{

}

void blockmsgqueue::addMsg(const char *msgPack)
{
    m_pFreeMsgs->acquire(1);
    m_mutex.lock();
    char *msgIn = new char[m_msgSize];
    memcpy(msgIn, msgPack, m_msgSize);
    m_queue.enqueue(msgIn);
    m_mutex.unlock();
    m_pUsedMsgs->release(1);
}

void blockmsgqueue::getMsg(char *msgPack)
{
    m_pUsedMsgs->acquire(1);
    m_mutex.lock();
    char *msgOut = m_queue.dequeue();
    memcpy(msgPack, msgOut, m_msgSize);
    m_mutex.unlock();
    m_pFreeMsgs->release(1);
}

对这个类的解释:

m_maxMsgsNum:最大的队列数量就是可以操作内存块的块数。

m_msgSize:每小块内存的尺寸。

信号量:

QSemaphore(n):建立对象时可以给n个资源,就是给多少块内存。

void acquire(n):这个函数,操作一次就减少n个资源,如果现在资源不到n个就会阻塞(在这个项目中如果没有一个资源就阻塞等待能有可用的资源)。

void release(n):这个函数,操作一次就增加n个资源。

在操作同一块内存块组,需要两个信号量来配合使用,一个是空闲内存块的信号量m_pFreeMsgs,用来标识是否有可用的内存块,这个是给生产者使用的。另一个是已经使用了多少内存块的信号量m_pUsedMsgs,用来标识是否有转载有用户数据的内存块,这个是给消费者使用的。

m_pFreeMsgs = new QSemaphore(m_maxMsgsNum);

m_pUsedMsgs = new QSemaphore(0);

这里是预先设定好信号量,预示着有10个空的内存块,0个装载用户数据的内存块

队列:

队列是一种数据结构,一种先入先出的数据结构

enqueue:入队

dequeue:出队

这个函数要将数据装载在共享内存块组内

void blockmsgqueue::addMsg(const char *msgPack)

{

m_pFreeMsgs->acquire(1);//用掉一个内存块,在下面要装载数据了

m_mutex.lock();//因为要操作同一块内存,就要锁住防止数据出问题

char *msgIn = new char[m_msgSize];

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

なかはらさん

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

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

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

打赏作者

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

抵扣说明:

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

余额充值