实现一个交易场所: 循环队列两个角色:
- 生产者:需要申请空间资源(P操作),然后释放数据资源(V操作)
- 消费者:需要申请数据资源(P操作),然后释放空间资源(V操作)
- 三种关系: 生产者与生产者(互斥)、生产者与消费者(同步(主要)和互斥)和消费者与消费者(互斥)
- 队列:数组模拟
- 容量:由用户给定
- 空间资源信号量:队列的容量大小
- 数据资源信号量:开始为0
- 生产者的下标位置:开始为0
- 消费者的下标位置:开始为0
#include<iostream>#include<string.h>#include<vector>#include<semaphore.h>#include<pthread.h>#include<unistd.h>using namespace std;//生产者:需要申请空间资源(P操作),然后释放数据资源(V操作)//消费者:需要申请空间资源(P操作),然后释放空间资源(V操作)template<class T>class RingQueue{public:RingQueue(int capacity = 5):_capacity(capacity),_rq(capacity),_c_index(0),_p_index(0){//初始化空间资源信号量,容量为5sem_init(&_blank_sem,0,_capacity);sem_init(&_data_sem,0,0);}~RingQueue(){sem_destroy(&_blank_sem);sem_destroy(&_data_sem);}private:void P(sem_t& sem){sem_wait(&sem);}void V(sem_t& sem){sem_post(&sem);}public:void GetData(T& data){// consumer申请数据资源P(_data_sem);data = https://www.huyubaike.com/biancheng/_rq[_c_index];_c_index = (_c_index + 1) % _capacity;// consumer释放格子资源V(_blank_sem);}void PutData(const T& data){// productor申请格子资源P(_blank_sem);_rq[_p_index] = data;_p_index = (_p_index + 1) % _capacity;// productor释放数据资源V(_data_sem);}private://vector容器模拟队列vector _rq;//队列的容量size_t _capacity;//空间资源信号量sem_t _blank_sem;//数据资源信号量sem_t _data_sem;//消费者的下标位置:开始为0int _c_index;//生产者的下标位置:开始为0int _p_index;};RingQueue *q ;void* Consumer(void* arg){long id = (long)arg;while (1){// 消费(取)数据int x;q->GetData(x);cout <<"consumer " << id << " consumes a data: " << x << endl;sleep(1);// 后面可注释,调整速度}}void* Productor(void* arg){long id = (long)arg;while (1){// 生产(放)数据int x = rand()%10 + 1;q->PutData(x);cout << "productor " << id << " produncs a data: " << x<< endl;sleep(1);// 后面可注释,调整速度}}int main(){ // 创建一个交易场所q = new RingQueue<int>();srand((size_t)time(nullptr));pthread_t p, c;pthread_create(&p, nullptr, Productor, (void*)(1));pthread_create(&c, nullptr, Consumer, (void*)(1));pthread_join(p, nullptr);pthread_join(c, nullptr);delete q;return EXIT_SUCCESS;}
注意:生产者生成数据前需要申请空间资源信号量(P(_blank_sem)),申请不成功就挂起等待,等待信号量来了继续获得信号量,然后释放数据资源信号量(V(_data_sem))消费者消费数据前需要申请数据资源信号量(P(_data_sem)),申请不成功就挂起等待,等待信号量来了继续获得信号量,然后释放空间资源信号量(V(_blank_sem))运行结果如下:
- 生产者和消费者执行速度一致

文章插图
生产者生产完一个数据,然后消费者就消费了,二者步调一致,并发执行 。
- 生产者快,消费者慢

文章插图
生产者速度快,一下字就把队列塞满了数据(开始时二者步调不一致),接着生产者如果再去申请空间信号量,此时已经申请不到了,只能挂起等待,消费者消费数据是否空间信号量,这是生产者才可以继续生产,可以看出,在后面大部分时间,二者步调恢复一致了,且速度随消费者 。
经验总结扩展阅读
- 2023年西安7月份气温多少度 西安7月份适合旅游吗
- 迪士尼可以带饭团进去吃吗 上海迪士尼可以带三明治进去吗
- 椰汁喝了有什么好处 椰汁喝了会长胖吗
- 红烧肉吃多了会头晕吗 吃了太多肉会有什么影响
- 2023年6月21日夏至,夏至三庚入头伏,23年入伏时间确定
- 2022年农历腊月二十三是装修最佳吉日吗
- 2023年四川成都五险一金缴费标准一览表 2023年四川成都五险一金每月多少钱
- 2023年农历正月初三是不是装修的好日子
- 社保如何查询交多久查看自己的社保缴纳方法看这里!
- 上海社保缴费标准2023 上海个人社保需要交多少钱