1.哲学家进餐问题
五个哲学家围着一张圆桌,每个哲学家免签放着食物。哲学家的生活有两种交替活动:吃饭以及思考。当一个哲学家吃法时,需要先拿起自己左右两边的两根筷子,并且一次只能拿起一根筷子。
下面是一种错误的解法,如果所有哲学家同时拿起左手边的筷子,那么所有哲学家都在等到其他哲学家吃完并释放自己手中的筷子,导致死锁。
1 2 3 4 5 6 7 8 9 10 11 12 #define N 5 void philosopher (int i) { while (TRUE) { think(); take(i); take((i+1 )%N); eat(); put(i); put((i+1 )%N); } }
为了防止死锁的发生,可以设置两个条件:
必须同时拿起左右两根筷子;
只有在两个邻居都没有进餐的情况下才允许进餐。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #define N 5 #define LEFT (i + N - 1) % N #define RIGHT (i + 1) % N #define THINKING 0 #define HUNGRY 1 #define EATING 2 typedef int semaphore;int state[N]; semaphore mutex = 1 ; semaphore s[N]; void philosopher (int i) { while (TRUE) { think(i); take_two(i); eat(i); put_two(i); } } void take_two (int i) { down(&mutex); state[i] = HUNGRY; check(i); up(&mutex); down(&s[i]); } void put_two (i) { down(&mutex); state[i] = THINKING; check(LEFT); check(RIGHT); up(&mutex); } void eat (int i) { down(&mutex); state[i] = EATING; up(&mutex); } void check (i) { if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] !=EATING) { state[i] = EATING; up(&s[i]); } }
2.读者-写者问题
允许多个进程同时对数据进行读操作,但是不允许读和写以及写和写操作同时发生。
一个整型变量count记录在对数据进行读操作的进程数量,一个互斥量count_mutex用于对count加锁,一个互斥量data_mutex用于对读写的数据加锁。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 typedef int semaphore;semaphore count_mutex = 1 ; semaphore data_mutex = 1 ; int count = 0 ;void reader () { while (TRUE) { down(&count_mutex); count++; if (count == 1 ) down(&data_mutex); up(&count_mutex); read(); down(&count_mutex); count--; if (count == 0 ) up(&data_mutex); up(&count_mutex); } } void writer () { while (TRUE) { down(&data_mutex); write(); up(&data_mutex); } }