生产消费模型之环形队列

Makefile

cpp 复制代码
cp: testMain.cc
	g++ -o cp testMain.cc -std=c++11 -lpthread  
  
.PHONY: clean  
  
clean:  
	rm -rf cp

ringQueue.hpp

cpp 复制代码
#ifndef RINGQUEUE_HPP
#define RINGQUEUE_HPP

#include <iostream>
#include <vector>
#include <pthread.h>
#include "sem.hpp"
#include <unistd.h>

const int g_default_num = 5;

template <typename T>
class RingQueue
{
public:
    RingQueue(int default_num = g_default_num)
        : _ring_queue(default_num), _num(default_num), c_step(0), p_step(0), spaceSem(default_num), dataSem(0)
    {
        pthread_mutex_init(&clock, nullptr);
        pthread_mutex_init(&plock, nullptr);
    }
    void push(const T &in)
    {
        spaceSem.P();
        pthread_mutex_lock(&plock);
        _ring_queue[p_step++] = in;
        p_step %= _num;
        dataSem.V();
        pthread_mutex_unlock(&plock);
    }
    void pop(T *out)
    {
        dataSem.P();
        pthread_mutex_lock(&clock);
        *out = _ring_queue[c_step++];
        c_step %= _num;
        spaceSem.V();
        pthread_mutex_unlock(&clock);
    }
    void debug()
    {
        std::cerr << "size: " << _ring_queue.size() << " num: " << _num << std::endl;
    }
    ~RingQueue()
    {
        pthread_mutex_destroy(&clock);
        pthread_mutex_destroy(&plock);
    }

private:
    std::vector<T> _ring_queue;
    int _num;
    int c_step;   // 消费下标
    int p_step;   // 生产下标
    Sem spaceSem; // 空间资源
    Sem dataSem;  // 数据资源
    pthread_mutex_t clock;
    pthread_mutex_t plock;
};

#endif

sem.hpp

cpp 复制代码
#ifndef SEM_HPP
#define SEM_HPP

#include <iostream>
#include <semaphore.h>

class Sem
{
public:
    Sem(int value)
    {
        sem_init(&_sem, 0, value);
    }

    void P()
    {
        sem_wait(&_sem);
    }

    void V()
    {
        sem_post(&_sem);
    }

    ~Sem()
    {
        sem_destroy(&_sem);
    }

private:
    sem_t _sem;
};

#endif

testMain.cc

cpp 复制代码
#include "ringQueue.hpp"

void *consumer(void *arg)
{
    RingQueue<int> *rq = (RingQueue<int> *)arg;
    while (true)
    {
        sleep(1);
        int x;
        rq->pop(&x);
        std::cout << "消费:" << x << "[" << pthread_self() << "]" << std::endl;
    }
}

void *productor(void *arg)
{
    RingQueue<int> *rq = (RingQueue<int> *)arg;
    while (true)
    {
        int x = rand() % 100 + 1;
        rq->push(x);
        std::cout << "生产:" << x << "[" << pthread_self() << "]" << std::endl;

    }
}

int main()
{
    srand((unsigned int)time(nullptr));
    pthread_t c[3], p[2];
    RingQueue<int> *rq = new RingQueue<int>(4);
    rq->debug();
    pthread_create(c, nullptr, consumer, (void *)rq);
    pthread_create(c + 1, nullptr, consumer, (void *)rq);
    pthread_create(c + 2, nullptr, consumer, (void *)rq);

    pthread_create(p, nullptr, productor, (void *)rq);
    pthread_create(p + 1, nullptr, productor, (void *)rq);

    pthread_join(c[0], nullptr);
    pthread_join(c[1], nullptr);
    pthread_join(c[2], nullptr);

    pthread_join(p[0], nullptr);
    pthread_join(p[1], nullptr);
}
相关推荐
不爱学英文的码字机器8 小时前
推荐算法梳理,六种主流模型与九步训练流程
算法·机器学习·推荐算法
白狐_7989 小时前
408数据结构第5章:树与二叉树②——遍历、线索树、森林与哈夫曼
数据结构·算法·深度优先
致Great12 小时前
科研人的 AI,不该只回答问题:我用字节TraeWork 跑了一遍真实研究任务
算法
纵有疾風起12 小时前
线性表的定义与基本操作 — 从逻辑结构到 ADT 接口
数据结构·算法·408·线性表·adt
测试_AI_一辰13 小时前
AI Agent 评测最隐蔽的坑-记忆
人工智能·算法·ai·自动化·ai编程
lucas_AI13 小时前
给YOLO检测器插 LoRA,'插对地方'比'插什么'更要命
人工智能·算法
LuminousCPP13 小时前
数据结构-时间与复杂度|时间/空间复杂度 + 两道力扣练习 + 二分查找复盘
c语言·数据结构·经验分享·算法·leetcode
Nil20813 小时前
leetcode 三数之和
数据结构·算法·leetcode
小小龙学IT14 小时前
C++ std::vector 底层实现深度解析:内存布局、扩容策略、移动语义与迭代器失效
开发语言·c++·算法
noipp14 小时前
推荐题目:洛谷 P16689 出征
java·开发语言·数据结构·c++·算法·洛谷·luogu