简单的生产-消费者程序

 1 #include <stdlib.h>
 2 #include <pthread.h>
 3 #include <stdio.h>
 4 #include <sys/unistd.h>
 5 
 6 #define PRINT_LINE  printf("FILE: %s,  LINE: %d
", __FILE__, __LINE__);
 7 #define CYCLE_TIME  (5)
 8 typedef struct msg {
 9     struct msg *prev;
10     struct msg *next;
11     int num;
12 } *pMsg;
13 
14 pMsg head;
15 pMsg tail;
16 pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
17 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
18 void printList();
19 void *consumer(void *p)
20 {
21     struct msg *mp = NULL;
22     for (;;) {
23     pthread_mutex_lock(&lock);
24     while (head == NULL && tail == NULL) {
25         printf("head is: %p, tail is: %p
", head, tail);
26         pthread_cond_wait(&has_product, &lock);
27     }
28     //printList();
29     mp = tail;
30     //if tail point the first Node, tail->next is NULL, and tail->prev is also NULL!
31     //So, in this condition, tail point to NULL after statement "tail = tail->prev;"
32     //this happened before second node is produced, because consumer get the lock
33     tail = tail->prev;
34     if (tail) {//tail not point to first
35         tail->next = NULL;
36     }
37     else //tail point to first, so after consume node, List is EMPTY!
38         head = NULL;//init List to NULL, so producer will add the next node to 
39                     //List and arise tail to it, add consumer will wait until List is Not EMPTY.
40     pthread_mutex_unlock(&lock);
41     printf("Consume	%d
", mp->num);
42     free(mp);        //PRINT_LINE
43     sleep(rand() % CYCLE_TIME);
44     }
45 }
46 
47 void *producer(void *p)
48 {
49     struct msg *mp;
50     for (;;) {
51     mp = malloc(sizeof(struct msg));
52     mp->num = rand() % 1000 + 1;
53     printf("Produce	%d
", mp->num);
54     pthread_mutex_lock(&lock);
55     mp->prev = NULL;
56     mp->next = head;
57     if (tail == NULL) {    //if the first Node is consumed
58         //before the second node is produced,
59         //this statement arise tail to second node.
60         tail = mp;
61     }
62     if (head)
63         head->prev = mp;
64     head = mp;
65     //printList();
66     pthread_mutex_unlock(&lock);
67     pthread_cond_signal(&has_product);
68 
69     sleep(rand() % CYCLE_TIME);
70     }
71 }
72 
73 int main(int argc, char *argv[])
74 {
75     head = tail = NULL;
76     pthread_t pid, cid;
77     srand(time(NULL));
78     pthread_create(&pid, NULL, producer, NULL);
79     pthread_create(&cid, NULL, consumer, NULL);
80     pthread_join(pid, NULL);
81     pthread_join(cid, NULL);
82     return 0;
83 }
84 
85 void printList()
86 {
87     pMsg mp=NULL;
88     printf("------------List Start ----------
");
89     mp = head;
90     while (mp) {
91     printf
92         ("element: mp - %p, mp->prev - %p, mp->num - %d, mp->next - %p;
",
93          mp, mp->prev, mp->num, mp->next);
94     printf("head: %p, tail: %p
", head, tail);
95     mp = mp->next;
96     }
97     printf("------------List End ----------
");
98 }

参考的<<Linux C 一站式编程>> "第35章 线程 第3节 线程同步"的代码和习题

原文地址:https://www.cnblogs.com/freudshow/p/5159389.html