该程序通过一个生产者-消费者的例子来展现线程间的同步状况,具体形式为生产者生产一个构造体串在链表的表头上,消费者从表头取走构造体,生产者未生产或生产的曾经被拿完,则消费者须要挂起期待.

本文通过两种链表形式来进行实现,留神是在linux环境下编译链接:
1、生产者和消费者拜访链表的程序是LIFO的。

  1 #include <stdlib.h>  2 #include <pthread.h>  3 #include <stdio.h>  4   5 struct msg {  6     struct msg *next;  7     int num;  8 };  9  10 struct msg *head; 11 pthread_cond_t has_product = PTHREAD_COND_INITIALIZER; 12 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 13  14 void *consumer(void *p) 15 {    16     struct msg *mp; 17      18     for (;;) { 19         pthread_mutex_lock(&lock); 20         while (head == NULL) 21             pthread_cond_wait(&has_product, &lock); 22         mp = head; 23         head = mp->next; 24         pthread_mutex_unlock(&lock); 25         printf("Consume %d\n", mp->num); 26         free(mp); 27         sleep(rand() % 5); 28     } 29 } 30  31 void *producer(void *p) 32 { 33     struct msg *mp; 34     for (;;) { 35         mp = malloc(sizeof(struct msg)); 36         mp->num = rand() % 1000 + 1; 37         printf("Produce %d\n", mp->num); 38         pthread_mutex_lock(&lock); 39         mp->next = head; 40         head = mp; 41         pthread_mutex_unlock(&lock); 42         pthread_cond_signal(&has_product); 43         sleep(rand() % 5); 44     } 45 } 46 

2、生产者和消费者拜访链表的程序是FIFO的。

  1 #include<stdio.h>  2 #include<stdlib.h>  3 #include<pthread.h>  4 #include<unistd.h>  5 /* 程序演示了一个生产者-消费者的例子,生产者生产一个构造体串在链表的表头上,消费者  6  * 从表尾取走构造体。留神: 不肯定产生一次就取走一次,尽管产生一次就唤醒一次消费者  7  * 但有可能此时并未调度消费者线程运行,但取走的肯定是表尾的构造体,即最快生产剩下未被取走的即FIFO */  8 struct msg  9 {    10     struct msg *next; 11     int num; 12 }; 13  14 struct msg *head; 15 pthread_cond_t has_product = PTHREAD_COND_INITIALIZER; 16 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 17  18 void *consumer(void *p) 19 { 20     struct msg *mp; 21     for (;;) 22     { 23         pthread_mutex_lock(&lock); 24         struct msg *t = NULL; 25         while (head == NULL){ 26             pthread_cond_wait(&has_product, &lock);//直到producer生产处至多一个mp,才会唤醒此处期待的以has_pr    oduct为Condition Variable的消费者线程 27         } 28         if (head->next != NULL) 29         { 30                 mp = head; 31                 t = head; 32                 while(mp->next !=NULL) 33                 { 34                         mp = mp->next; 35                 } 36                 while(t->next != mp){ 37                         t = t->next; 38                 } 39                 t->next = mp->next; 40         } 41         else 42         { 43             mp = head; 44             head = mp->next; 45         } 46         pthread_mutex_unlock(&lock); 47         printf("Consume %d\n", mp->num); 48         free(mp); 49         sleep(rand() % 5); 50     } 51 } 52  53 void *producer(void *p) 54 { 55     struct msg *mp; 56     for (;;) 57     { 58         mp = malloc(sizeof(struct msg)); 59         mp->num = rand() % 1000 + 1; 60         printf("Produce %d \n", mp->num); 61         pthread_mutex_lock(&lock); 62         mp->next = head; 63         head = mp; 64         pthread_mutex_unlock(&lock); 65         pthread_cond_signal(&has_product);//唤醒以has_product为条件变量的wait中的一个线程 66         sleep(rand() % 5); 67     } 68 } 69  70 int main(int argc, char *argv[]) 71 { 72     pthread_t pid, cid; 73     srand(time(NULL)); 74     pthread_create(&pid, NULL, producer, NULL); 75     pthread_create(&cid, NULL, consumer, NULL); 76     pthread_join(pid, NULL); 77     pthread_join(cid, NULL); 78     return 0; 79 }

在linux下的编译链接运行命令如下:
gcc sourcecode.c -o sourcecode -lpthread

FIFO(先生产先取用)形式执行后果如下图: