diff --git a/notes/计算机操作系统.md b/notes/计算机操作系统.md index 716bbf76..6f4bae92 100644 --- a/notes/计算机操作系统.md +++ b/notes/计算机操作系统.md @@ -273,15 +273,15 @@ down 和 up 操作需要被设计成原语,不可分割,通常的做法是 typedef int semaphore; semaphore mutex = 1; void P1() { - down(mutex); + down(&mutex); // 临界区 - up(mutex); + up(&mutex); } void P2() { - down(mutex); + down(&mutex); // 临界区 - up(mutex); + up(&mutex); } ``` @@ -305,21 +305,21 @@ semaphore full = 0; void producer() { while(TRUE){ int item = produce_item(); - down(empty); - down(mutex); + down(&empty); + down(&mutex); insert_item(item); - up(mutex); - up(full); + up(&mutex); + up(&full); } } void consumer() { while(TRUE){ - down(full); - down(mutex); + down(&full); + down(&mutex); int item = remove_item(); - up(mutex); - up(empty); + up(&mutex); + up(&empty); consume_item(item); } } @@ -452,23 +452,23 @@ int count = 0; void reader() { while(TRUE) { - down(count_mutex); + down(&count_mutex); count++; - if(count == 1) down(data_mutex); // 第一个读者需要对数据进行加锁,防止写进程访问 - up(count_mutex); + if(count == 1) down(&data_mutex); // 第一个读者需要对数据进行加锁,防止写进程访问 + up(&count_mutex); read(); - down(count_mutex); + down(&count_mutex); count--; - if(count == 0) up(data_mutex); - up(count_mutex); + if(count == 0) up(&data_mutex); + up(&count_mutex); } } void writer() { while(TRUE) { - down(data_mutex); + down(&data_mutex); write(); - up(data_mutex); + up(&data_mutex); } } ``` @@ -483,44 +483,70 @@ void writer() { ```c #define N 5 -#define LEFT (i + N - 1) % N -#define RIGHT (i + N) % N -typedef int semaphore; -semaphore chopstick[N]; void philosopher(int i) { - while(TURE){ + while(TRUE) { think(); - down(chopstick[LEFT[i]]); - down(chopstick[RIGHT[i]]); + take(i); // 拿起左边的筷子 + take((i+1)%N); // 拿起右边的筷子 eat(); - up(chopstick[RIGHT[i]]); - up(chopstick[LEFT[i]]); + put(i); + put((i+1)%N); } } ``` -为了防止死锁的发生,可以加一点限制,只允许同时拿起左右两边的筷子。方法是引入一个互斥量,对拿起两个筷子的那段代码加锁。 +为了防止死锁的发生,可以加一点限制,一个哲学家只有在两个邻居都没有进餐的情况下才允许进餐。 ```c -semaphore mutex = 1; +#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(TURE){ + while(TRUE) { think(); - down(mutex); - down(chopstick[LEFT[i]]); - down(chopstick[RIGHT[i]]); - up(mutex); + take_two(i); eat(); - down(mutex); - up(chopstick[RIGHT[i]]); - up(chopstick[LEFT[i]]); - up(mutex); + put_tow(i); + } +} + +void take_two(int i) { + down(&mutex); + state[i] = HUNGRY; + test(i); + up(&mutex); + down(&s[i]); +} + +void put_tow(i) { + down(&mutex); + state[i] = THINKING; + text(LEFT); + test(RIGHT); + up(&mutex); +} + +void test(i) { // 尝试拿起两把筷子 + if(state[i] == HUNGRY && state[LEFT] != EATING + && state[RIGHT] !=EATING) { + state[i] = EATING; + up(&s[i]); } } ``` + + + # 第三章 死锁 ## 死锁的必要条件