9.经典进程同步问题
生产者消费者问题
读者-写者问题
哲学家进餐问题
哲学家就餐问题讨论
为防止死锁发生可采取的措施
- 最多允许4个哲学家同时坐在桌子周围
- 仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子
- 给所有哲学家编号,基数号的哲学家必须首先拿左边的筷子,偶数号的哲学 家则反之
- 为了避免死锁,把哲学家分为三种状态,思考,饥饿,进食,并且一次拿到两只 筷子, 否则不拿
每个哲学家拿起第一根筷子一定时间后,若拿不到第二根筷子,再放下第一根筷子
linux下的消费生产商品代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <semaphore.h>
2 #include <unistd.h>
3 #include <sys/types.h>
4 #include <pthread.h>
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <errno.h>
9 #include <string.h>
10
11 #define ERR_EXIT(m) \
12 do \
13 { \
14 perror(m); \
15 exit(EXIT_FAILURE); \
16 }while(0)
17
18 #define CONSUMERS_COUNT 2 //消费者人数
19 #define PRODUCERS_COUNT 2 //生产者人数
20 #define BUFFSIZE 5
21
22 int g_buffer[BUFFSIZE];//缓冲区数目
23
24 unsigned short in = 0; //放入产品的指针(生产到哪个缓冲区)
25 unsigned short out = 0;//取出缓冲区指针(在哪个缓冲区消费的)
26 unsigned short produce_id = 0;
27 unsigned short consume_id = 0;
28
29 sem_t g_sem_full; //缓冲区可以生产的产品数 = BUFFSIZE
30 sem_t g_sem_empty; //缓冲区可以消费的产品数 = 0
31 pthread_mutex_t g_mutex;//互斥信号量
32
33 pthread_t g_thread[CONSUMERS_COUNT + PRODUCERS_COUNT];
34
35 void *consume(void *arg)
36 {
37 int i;
38 int num = (int)arg;
39 while(1)
40 {
41 sem_wait(&g_sem_empty);//wait()操作
42 pthread_mutex_lock(&g_mutex);//互斥锁
43
44 //遍历缓冲区,看看有哪些缓冲区是可以生产消费的
45 for(i=0;i<BUFFSIZE;i++)
46 {
47 printf("%d 缓存区",i);
48 if(g_buffer[i] == -1)
49 printf("%s","为空");
50 else
51 printf("%d",g_buffer[i]);
52
53 if(i==out)
54 printf("\t------消费");
55
56 printf("\n");
57 }
58
59 //produce()操作(生产产品)
60 consume_id = g_buffer[out];
61 printf("%d 开始生产 产品 %d\n",num,consume_id);
62 g_buffer[out] = -1;
63 //将取出缓存区的指针偏移1(下个生产的位置)
64 out = (out+1) % BUFFSIZE;
65 printf("%d 生产商品 %d 结束",num,consume_id);
66 pthread_mutex_unlock(&g_mutex);
67 sem_post(&g_sem_full);//signal()操作
68 sleep(1);
69 }
70 return NULL;
71
72 }
73
74 void *produce(void *arg)
75 {
76 int num = (int)arg;
77 int i;
78 while(1)
79 {
80 sem_wait(&g_sem_full);
81 pthread_mutex_lock(&g_mutex);
82
83 //遍历缓冲区,看看有哪些缓冲区是可以生产产品的
84 for(i=0;i<BUFFSIZE;i++)
85 {
86 printf("%d 缓存区",i);
87 if(g_buffer[i] == -1)
88 {
89
90 printf("%s","为空");
91 }
92 else
93 printf("%d",g_buffer[i]);
94
95 if(i==in)
96 printf("\t------生产");
97
98 printf("\n");
99 }
100
101 printf("%d 开始生产产品 %d\n",num,produce_id);
102 g_buffer[in] = produce_id;
103 in = (in+1)%BUFFSIZE;
104 printf("%d 产品结束生产 %d\n",num,produce_id++);
105 pthread_mutex_unlock(&g_mutex);
106 sem_post(&g_sem_empty);
107 sleep(5);
108 }
109 return NULL;
110 }
111
112 int main()
113 {
114 int i;
115 for(i=0;i<BUFFSIZE;i++)
116 g_buffer[i] = -1;
117
118 sem_init(&g_sem_full,0,BUFFSIZE);
119 sem_init(&g_sem_empty,0,0);
120
121 pthread_mutex_init(&g_mutex,NULL);
122
123 for(i=0;i<CONSUMERS_COUNT;i++)
124 pthread_create(&g_thread[i],NULL,consume,(void *)i);
125
126 for(i=0;i<CONSUMERS_COUNT;i++)
127 pthread_create(&g_thread[i],NULL,produce,(void *)i);
128
129 for(i=0;i<CONSUMERS_COUNT;i++)
130 pthread_join(g_thread[i],NULL);
131
132 sem_destroy(&g_sem_full);
133 sem_destroy(&g_sem_empty);
134 sem_destroy(&g_mutex);
135
136 return 0;
137
138 }
linux下哲学家进餐代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <pthread.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5
6 #define N 5
7 #define LEFT (i+N-1)%N
8 #define RIGHT (i+1)%N
9 #define THINK_TIME 3
10 #define EAT_TIME 2
11
12 enum { THINKING, HUNGRY, EATING } state[N];
13
14 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER, s[N];
15
16 //如果能吃法就吃饭
17 void test(int i)
18 {
19 if (state[i] == HUNGRY
20 && state[LEFT] != EATING
21 && state[RIGHT] != EATING)
22 {
23 state[i] = EATING;
24 pthread_mutex_unlock(&s[i]);//哲学家饱了
25 }
26 }
27
28 //第i个哲学家饿了
29 void take_forks(int i)
30 {
31 pthread_mutex_lock(&mutex);
32 state[i] = HUNGRY;
33 test(i);
34 pthread_mutex_unlock(&mutex);
35 pthread_mutex_lock(&s[i]);//等待哲学家饿了
36 }
37
38 //第i个哲学家思考
39 void put_forks(int i)
40 {
41 pthread_mutex_lock(&mutex);
42 state[i] = THINKING;
43 test(LEFT);
44 test(RIGHT);
45 pthread_mutex_unlock(&mutex);
46 }
47
48 void think(int i)
49 {
50 printf("philosopher %d is thinking...\n", i);
51 sleep(THINK_TIME);
52 }
53
54 void eat(int i)
55 {
56 printf("philosopher %d is eating...\n", i);
57 sleep(EAT_TIME);
58 }
59
60 //线程函数
61 void* phi(void* vargp)
62 {
63 int i = *(int*)vargp;
64 while (1)
65 {
66 think(i);
67 take_forks(i);
68 eat(i);
69 put_forks(i);
70 }
71 return NULL;
72 }
73
74 int main()
75 {
76 int i;
77 pthread_t tid[N];
78 for (i = 0; i < N; i++)
79 pthread_create(&tid[i], NULL, phi, (void*)(&i));
80 for (i = 0; i < N; i++)
81 pthread_join(tid[i], NULL);
82 return 0;
83 }
注意编译时候后面要加上 -lpthread