利用信号量实现进程互斥
semaphore mutex=1;
Pa(){
while(1){
wait(mutex);
临界区;
signal(mutex);
剩余区;
}
}
Pb(){
while(1){
wait(mutex);
临界区;
signal(mutex);
剩余区;
}
}
利用信号量实现前驱关系
//s1->s2(a),s1->s3(b),s2->s4(c),s2->s5(d),s3->s6(e),s4->s6(f),s5->s6(g)
//s1~s6表示六条语句的前驱关系
p1(){s1; signal(a);signal(b);}
p2(){wait(a);s2; signal(c);signal(d);}
p3(){wait(b);s3;signal(e);}
p4(){wait(c);s4; signal(f);}
p5(){wait(d);s5;signal(g);}
p6(){ wait(e); wait(f);wait(g);s6;}
void main{
semaphore a,b,c,d,e,f,g;
a.value=b.value=c.value=d.value=e.value=f.value=g.value=0;
cobegin
p1();p2();p3();p4();p5();p6();
coend
}
生产者-消费者问题
假定生产者和消费者之间的公用缓冲池有n个缓冲区,利用mutex实现诸进程对缓冲池的互斥使用;利用信号量empty,full分别表示缓冲池的空缓冲区和满缓冲区的数量(缓冲区空闲的数量和生产的物品的数量)。又假定只要缓冲区未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池取走一个消息。
描述如下
void proceducer(){
while(TRUE){
product an item a;
. . .
wait(empty);
wait(mutex);
buffer[in]=nextp;
in=(in+1)%n; //对缓冲区的位置循环使用
signal(mutex);
signal(full);
}
}
void consumer(){
while(TRUE){
wait(full);
wait(mutex);
nextc=buffer[out];
out=(out+1)%n;
signal(metux);
signal(empty);
consume the item in nextc;
. . .
}
}
void main(){
int in,out=0;
item buffer[n];
semaphore mutex=1,empty=n,full=0;
cobegin
producer();consumer();
coend
}
哲学家进餐问题
五位哲学家坐在一张圆桌上并且在左右两只筷子之间,桌子上一共有五只筷子用来吃饭,哲学家的生活方式就是,不是吃饭就是思考交替进行。平时一个哲学家思考,饥饿时试图拿取靠近他的左右两只筷子,获得两只筷子才能吃饭,吃饭后继续思考。
philosopher_i(){ //i=1,2,3,4,5
do{
... //think
swait(chopstick[(i+1)%5],chopstick[i]);
.... //eat
signal(chopstick[(i+1)%5],chopstick[i]);
}while(TRUE)
}
void main(){
semaphore chopstick[5]={1,1,1,1,1} ;
cobegin
philosopher_1(); philosopher_2(); philosopher_3(); philosopher_4(); philosopher_5();
coend
}
AND型信号量能够很好解决哲学家进餐问题,也能有效避免死锁产生(比如五个人同时那一只筷子的僵持状态)
读者写者问题
一个数据文件可以被多个进程共享,把只要求读该文件的进程称为“Reader进程”,其他进程则称为“Write进程”。允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱。但是不允许
一个Writer进程和其他Reader进程或Writer进程同时访问共享对象。 因为这样的访问会引起混乱,所谓的读者-写者问题,是保证Writer进程必须与其他进程互斥的访问共享对象的同步问题。
利用记录型信号量解决
void reader_i(){ //i=1,2,3,....,n,......
do{
wait(rmutex);
if(readercount==0)wait(wmutex);
readercount++;
signal(rmutex);
....
perform read operation;
....
wait(rmutex);
readcount--;
if(readcount==0)signal(wmutex);
signal(rmutex);
}while(TRUE);
}
void writer_i(){ //i=1,2,3,...,n,...
do{
wait(wmutex);
perform write operation;
signal(rmutex);
}while(TRUE);
}
void main(){
semaphore rmutex=1,wmutex=1;
int readercount=0; //因为所有的读者进程都能访问修改readercount变量,所以需要设置rmutex来保护
cobegin
reader_1();reader_2();....;reader_n();
writer_1();writer_2();.....;writer_n();
coend
}