1、此代码为借助条件变量结合互斥锁完成生产者与消费者模型,代码中主要关注锁和条件变量的定义、初始化、使用(加锁、解锁)以及释放(销毁)。
2、代码:
1 #include <cstdio>
2 #include <cstdlib>
3 #include <cstring>
4 #include <unistd.h>
5 #include <pthread.h>
6
7 void err_thread(int ret, const char *str)
8 {
9 if(ret != 0){
10 fprintf(stderr, "%s:%s\n", str, strerror(ret));
11 pthread_exit(NULL);
12 }
13 }
14
15 struct msg{
16 int num;
17 struct msg *next;
18 };
19
20 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
21 pthread_cond_t has_data = PTHREAD_COND_INITIALIZER;
22
23 struct msg *head = nullptr;
24
25 void *producer(void *arg)
26 {
27 int ret;
28
29 while(1){
30 struct msg *mp = (struct msg*)malloc(sizeof(struct msg));
31 if(!mp){
32 perror("malloc error\n");
33 }
34
35 mp->num = rand()%1000 + 1;
36 printf("--------producer:%d\n", mp->num);
37
38 ret = pthread_mutex_lock(&mutex);
39 err_thread(ret, "producer: pthread_mutex_lock error");
40
41 mp->next = head;
42 head = mp;
43
44 ret = pthread_mutex_unlock(&mutex);
45 err_thread(ret, "producer: pthread_mutex_unlock error");
46
47 ret = pthread_cond_signal(&has_data);
48 err_thread(ret, "producer: pthread_cond_signal error");
49
50 sleep(rand()%3);
51 }
52
53 return NULL;
54 }
55
56 void *consumer(void *arg)
57 {
58 int ret;
59
60 while(1){
61 struct msg *mp = nullptr;
62
63 ret = pthread_mutex_lock(&mutex);
64 err_thread(ret, "consumer: pthread_mutex_lock error");
65 /*
66 // This "if" statement only applies to single comsumer mode
67 if(head == nullptr){
68 pthread_cond_wait(&has_data, &mutex);
69 }
70 */
71
72 // This "while" statement applies to multiple comsumer mode
73 while(head == nullptr){
74 ret = pthread_cond_wait(&has_data, &mutex);
75 err_thread(ret, "consumer: pthread_cond_wait error");
76 }
77
78 mp = head;
79 head = mp->next;
80
81 ret = pthread_mutex_unlock(&mutex);
82 err_thread(ret, "consumer: pthread_mutex_unlock error");
83
84 printf("-----consumer id %lu:%d\n", pthread_self(), mp->num);
85
86 free(mp);
87 sleep(rand()%3);
88 }
89 return NULL;
90 }
91
92 int main(int argc, char *argv[])
93 {
94 int ret;
95 pthread_t pid, cid1, cid2, cid3;
96
97 srand(time(NULL));
98
99 ret = pthread_create(&pid, NULL, producer, NULL);
100 err_thread(ret, "pthread_create producer error");
101
102 ret = pthread_create(&cid1, NULL, consumer, NULL);
103 err_thread(ret, "pthread_create consumer error");
104
105 ret = pthread_create(&cid2, NULL, consumer, NULL);
106 err_thread(ret, "pthread_create consumer error");
107
108 ret = pthread_create(&cid3, NULL, consumer, NULL);
109 err_thread(ret, "pthread_create consumer error");
110
111 ret = pthread_join(pid, NULL);
112 err_thread(ret, "pthread_join error");
113 ret = pthread_join(cid1, NULL);
114 err_thread(ret, "pthread_join error");
115 ret = pthread_join(cid2, NULL);
116 err_thread(ret, "pthread_join error");
117 ret = pthread_join(cid3, NULL);
118 err_thread(ret, "pthread_join error");
119
120 ret = pthread_mutex_destroy(&mutex);
121 err_thread(ret, "pthread_mutex_destroy error");
122
123 ret = pthread_cond_destroy(&has_data);
124 err_thread(ret, "pthread_cond_destroy error");
125
126 return 0;
127 }