生产者-消费者问题
假设在生产者和消费者之间的公用缓冲池中具有n个缓冲区,这时可利用互斥信号量mutex实现诸进程对缓冲池的互斥使用;利用empty和full分别表示缓冲池中空缓冲区和满缓冲区的数量。
int in=0,out=0;
item buffer[n];
semaphore mutex=1,empty=n,full=0;
void proceducer(){//生产者进程
do{
producer an item nextp;
...
wait(empty);//空间减一,若小于零则阻塞
wait(mutex);//生产消费互斥
buffer[in]=nextp;//公共缓冲池指针移动
in=(in+1)%n;
signal(mutex);
signal(full);//慢缓冲区+1
}while(TRUE);
}
void consumer(){//消费者进程
do{
wait(full);//满缓冲区-1 full<0时阻塞进程
wait(mutex);//互斥
nextc=buffer[out];
out=(out+1)%n;
signal(mutex);
signal(empty);
consumer the item in nextc;
...
}while(true);
}
void main(){
cobegin
proceducer();
consumer();
coend
}
注意:
①在每个程序中用于实现互斥的wait(mutex)和signal(mutex)必须成对的出现。
②对资源信号量empty和full的wait和signal操作,同样需要成对出现。但它们分别处于不同的程序中
2.利用AND信号量解决生产者-消费者问题
int in=0,out=0;
item buffer[n];
semaphore mutex=1,empty=n,full=0;
void proceducer(){
do{
producer an item nextp;
...
Swait(empty,mutex);
buffer[in]=nextp;
in=(in+1)%n;
Ssignal(mutex,full);
}while(TRUE);
}
void consumer(){
do{
Swait(full,mutex);
nextc=buffer[out];
out=(out+1)%n;
Ssignal(mutex,empty);
consumer the item in nextc;
...
}while(TRUE);
}
哲学家进餐问题
五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,他们的生活方式是交替的进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图去用其左右最靠近他的筷子,只有在谈到两只筷子时才能进餐。进餐毕,放下筷子继续思考。
1.利用记录型信号量解决哲学家进餐问题
筷子是临界资源,为了实现对筷子的互斥使用,可以用一个信号量表示一只筷子,有这五个信号量构成信号量数组。
semaphore chopstick[5]={1,1,1,1,1};//所有信号量均被初始化为1,第i为哲学家的活动可描述为:
do{
wait(chopstick[i]);//拿左边筷子
wait(chopstick[(i+1)%5]);//拿右边筷子
...
//eat
...
signal(chopstick[i]);//放左边筷子
signal(chopstick[(i+1)%5]);//放右边筷子
...
//think
...
}while(true);
死锁问题:五位哲学家同
时饥饿而各自拿起左边的筷子时,就会使五个信号量均为0;当他们在试图去拿右边的筷子时,都将因为无筷子可拿而无限期等待。
-
至多只允许有四位哲学家同事去拿左边的筷子,
-
仅当哲学家的左、右两只筷子均可用时,才允许他拿起筷子进餐。
-
规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子;而偶数号哲学家则相反
2.利用AND信号量机制解决哲学家进餐问题semaphore chopstick[5]={1,1,1,1,1};
do{
…
//think
…
Sswait(chopstick(i+1)%5],chopstick[i]);
…
//eat
…
Ssignal(chopstick[(i+1)%5],chopstick[i]);
)while[true]