http://blog.csdn.net/raykid13/archive/2008/10/16/3087858.aspx
訊號量結構使用C語言表示如下:
- typedef struct {
- int value;//記錄了這個訊號量的值
- struct process *list;//儲存正在等待這個訊號量的進程
- } semaphore;
wait()訊號量部分代碼如下:
- wait(semaphore *S) {
- S->value--;
- if(S->value < 0) {
- add this process to S->list;
- block();
- }
- }
signal()訊號量部分代碼如下:
- signal(semaphore *S) {
- S->value++;
- if(S->value <= 0) {
- remove a process P from S->list;
- wakeup(P);
- }
- }
一、The Bounded-Buffer Problem:
full初始化為0,empty初始化為n,mutex為1
- do{
- wait(full);
- wait(mutex);
- ...
- //remove an item from buffer to nextc
- ...
- signal(mutex);
- signal(empty);
- ...
- //consume the item in nextc
- ...
- } while(TRUE);
二、The Readers-Writers Problem:
wrt初始化為1,readcount初始化為0,mutex為1
寫者操作:
- do{
- wait(wrt);
- ...
- //writing is performed
- ...
- signal(wrt);
- } while(TRUE);
讀者操作:
- do{
- wait(mutex);//確保與signal(mutex)之間的操作不會被其他讀者打斷
- readcount++;
- if(readcount == 1)
- wait(wrt);
- signal(mutex);
- ...
- //reading is performed
- ...
- wait(mutex);
- readcount--;
- if(readcount == 0)
- signal(wrt);
- signal(mutex);
- } while(TRUE);
三、The Dining-Philosophers Problem:
所有的chopstick[5]全部初始化為1
- do{
- wait(chopstick[i]);
- wait(chopstick[(i+1)%5]);
- ...
- //eating
- ...
- signal(chopstick[i]);
- signal(chopstick[(i+1)%5]);
- ...
- //thinking
- ...
- } while(TRUE);
但是這個解決方案的最大問題在於它會出現死結。所以我認為應該增加一個訊號量mutex,並初始化為1:
- do{
- wait(mutex);
- wait(chopstick[i]);
- wait(chopstick[(i+1)%5]);
- signal(mutex);
- ...
- //eating
- ...
- wait(mutex);
- signal(chopstick[i]);
- signal(chopstick[(i+1)%5]);
- signal(mutex);
- ...
- //thinking
- ...
- } while(TRUE);
這樣由於確保了一位哲學家在拿起兩隻筷子的時間內其他哲學家不可以拿起任何一支筷子,從而破壞了死結出現需要的四個特徵中的Hold And Wait特徵,從而避免了死結的發生。
最後,死結發生的四個特徵包括:
1. Mutual exclusion;
2. Hold and wait;
3. No preemption;
4. Circular wait;
當四個條件全部滿足的時候,死結將有可能發生。