我在在使用条件变量的时候,如果有很多线程等待在同一个条件变量上,那么当条件满足的时候,唤醒的可能不是我们需要的那个线程,所以我们应该让不同的角色等待在不同的条件变量上,区分唤醒
生产者与消费者模型
生产者与消费者模型不属于23中设计模型中的一种,它只是一种编程的思想
简明来说,所谓生产者与消费者模型其实就是两种角色,三种关系
在生产者与消费者中保证这三种关系的实现,才能保证数据的安全
生产者与生产者:互斥
生产者与消费者:同步+互斥
消费者与消费者:互斥
生产者与消费者的应用场景
1.缓解峰值压力
2.解耦合
3.支持忙闲不均
模拟实现环形队列生产者与消费者模型
1 #include<iostream>
2 #include<vector>
3 #include<stdlib.h>
4 #include<semaphore.h>
5 #include<pthread.h>
6 #include<unistd.h>
7 using namespace std;
8
9 #define NUM 16
10
11 class RingQueue{
12 private:
13 vector<int> q;
14 int cap;
15 sem_t data_sem;
16 sem_t space_sem;
17 int consume_step;
18 int product_step;
19
20 public:
21 RingQueue(int _cap = NUM)
22 :cap(_cap)
23 {
24 q.resize(_cap);
25 sem_init(&data_sem, 0 ,0);
26 sem_init(&space_sem, 0 , cap);
27 consume_step = 0;
28 product_step = 0;
29 }
30
31 void PutData(const int &data)
32 {
33 sem_wait(&space_sem);
34 q[consume_step] = data;
35 consume_step++;
36 consume_step %= cap;
37 sem_post(&data_sem);
38 }
39
40 void GetData(int &data)
41 {
42 sem_wait(&data_sem);
43 data = q[product_step];
44 product_step++;
45 product_step %= cap;
46 sem_post(&space_sem);
47 }
48
49 ~RingQueue()
50 {
51 sem_destroy(&data_sem);
52 sem_destroy(&space_sem);
53 }
54 };
55
56 void *consumer(void *arg)
57 {
58 RingQueue *rqp = (RingQueue*)arg;
59 int data;
60 while(1)
61 {
62 rqp->GetData(data);
63 cout << "Consumer data done: " << data << endl;
64 sleep(1);
65 }
66 }
67
68
69 void *producter(void *arg)
70 {
71 RingQueue *rqp = (RingQueue*)arg;
72 //srand((unsigned long)time(NULL));
73 while(1)
74 {
75 int data = rand()%1024;
76 rqp->PutData(data);78 //sleep(1);
79 }
80 }
81
82 int main()
83 {
84 RingQueue *rq;
85
86 pthread_t c,p;
87 pthread_create(&c,NULL,consumer,(void*)&rq);
88 pthread_create(&p,NULL,producter,(void*)&rq);
89
90
91 pthread_join(c,NULL);
92 pthread_join(p,NULL);
93
94
95 return 0;
96 }
97
98
77 cout << "Product data done: " << data << endl;