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;
当四个条件全部满足的时候,死锁将有可能发生。