该程序通过一个生产者-消费者的例子来展现线程间的同步状况,具体形式为生产者生产一个构造体串在链表的表头上,消费者从表头取走构造体,生产者未生产或生产的曾经被拿完,则消费者须要挂起期待.
本文通过两种链表形式来进行实现,留神是在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(先生产先取用)形式执行后果如下图: