实现一个交易场所: 循环队列两个角色:
- 生产者:需要申请空间资源(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))运行结果如下:
- 生产者和消费者执行速度一致

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

文章插图
生产者速度快,一下字就把队列塞满了数据(开始时二者步调不一致),接着生产者如果再去申请空间信号量,此时已经申请不到了,只能挂起等待,消费者消费数据是否空间信号量,这是生产者才可以继续生产,可以看出,在后面大部分时间,二者步调恢复一致了,且速度随消费者 。
- 生产者慢,消费者快

文章插图
生产生产者生产完一个数据 , 数据信号量加1,空间信号量减1 , 然后消费者里马消费了一个数据,数据信号量减1 , 空间信号量加1,此时数据信号量为0 , 消费者再去申请数据信号量,申请不到就挂起等待,只能等生产者在去生产释放空间信号量 , 然后消费者才可以申请到 。可以看出的是,队列长时间是空的,二者步调一致 , 速度随生产者 。
推荐阅读
- 航海王热血航线三兄弟PVP技能连招攻略
- 三月不知肉味原本是孔子用来形容?
- 三星S22Ultra最新消息_三星S22Ultra手机曝光
- 三 Java多线程-ThreadPool线程池
- R数据分析:扫盲贴,什么是多重插补
- 原神三个耶然草的封印怎么解除
- 二 Java多线程-线程关键字
- 有的人夫妻俩都不上班,在家用电脑就可以赚到钱,比上班收入高多了,怎么赚钱的
- 一 Java多线程-线程生命周期
- 一加8pro屏幕分辨率是多少_一加8pro屏幕分辨率怎么样