简单的生产-消费者程序
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\n", __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\n", 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\t%d\n", 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\t%d\n", 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 ----------\n"); 89 mp = head; 90 while (mp) { 91 printf 92 ("element: mp - %p, mp->prev - %p, mp->num - %d, mp->next - %p;\n", 93 mp, mp->prev, mp->num, mp->next); 94 printf("head: %p, tail: %p\n", head, tail); 95 mp = mp->next; 96 } 97 printf("------------List End ----------\n"); 98 }
参考的<<Linux C 一站式编程>> "第35章 线程 第3节 线程同步"的代码和习题