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