9.经典进程同步问题

生产者消费者问题

 

 


读者-写者问题

 

 


哲学家进餐问题


哲学家就餐问题讨论

为防止死锁发生可采取的措施

  •   最多允许4个哲学家同时坐在桌子周围
  •   仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子
  •   给所有哲学家编号,基数号的哲学家必须首先拿左边的筷子,偶数号的哲学          家则反之
  •   为了避免死锁,把哲学家分为三种状态,思考,饥饿,进食,并且一次拿到两只          筷子, 否则不拿

每个哲学家拿起第一根筷子一定时间后,若拿不到第二根筷子,再放下第一根筷子


  linux下的消费生产商品代码:

  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("	------消费");
 55 
 56             printf("
");
 57         }
 58 
 59         //produce()操作(生产产品)
 60         consume_id = g_buffer[out];
 61         printf("%d 开始生产 产品 %d
",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("	------生产");
 97 
 98             printf("
");
 99         }
100 
101         printf("%d 开始生产产品 %d
",num,produce_id);
102         g_buffer[in] = produce_id;
103         in = (in+1)%BUFFSIZE;
104         printf("%d 产品结束生产 %d
",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 }
View Code

 linux下哲学家进餐代码

 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...
", i);
51     sleep(THINK_TIME);
52 }
53 
54 void eat(int i)
55 {
56     printf("philosopher %d is eating...
", 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 }
View Code

注意编译时候后面要加上 -lpthread

 

原文地址:https://www.cnblogs.com/xiaochi/p/8029636.html