经典进程的同步问题
1.生产者—消费者问题
问题:
若干进程通过有限的共享缓冲区交换数据。其中,“生产者”进程不断写入,而“消费者”进程不断读出;共享缓冲区共有N个;任何时刻只能有一个进程.可对共享缓冲区进行操作。
解决思路:
1)在访问公共缓冲区的时候,进程之间是互斥的
2)当缓冲区为空时,“消费者”进程不能读出
3)当缓冲区为满时,“生产者”进程不能写入
采用AND信号量解决问题:
semaphore full=0; //满缓冲区单元个数
semaphore empty=n; //空缓冲区单元个数
semaphore mutex=1; //互斥信号量:控制对临界资源的访问
char buffer[n];
int in=0,out=0;
char nextc,nextp;
void producer() //生产者进程
{
do {
produce an item nextp; //生产一个数据
Swait(empty,mutex); //空缓冲区数量减1;进入临界区
buffer[in]=nextp; //将一个数据送入缓冲池
in=(in+1) % n; //修改in指针
Ssignal(mutex , full);//退出临界区;,满缓冲区数量增1
}while(TRUE);
}
void consumer() //消费者进程
{
do{
Swait( full , mutex); //满缓冲区数减1,进入临界区
nextc=buffer[out]; //从缓冲区读出一个数据
out=(out+1) mod n; //修改out指针
Ssignal(mutex , empty);//退出临界区;空缓冲区数增1
consume the item in nextc; //消费一个数据
} while(TRUE);
}
//主程序运行
void main()
{ cobegin //进程之间并发执行
producer();
consumer();
coend
}
2.哲学家进餐的问题
问题:
有五个哲学家公用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,他们的生活方式是交替地进行思考和快餐,平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有他拿到两只筷子时才能进餐
解决思路:
临界资源:筷子
方法:
1)最多允许四个哲学家同时进餐
2)仅当哲学家的左、右两只筷子均可用,才允许他进餐。
3)规定奇数号哲学家先拿他左边的筷子,然后再去拿他右边的筷子;而偶数号哲学家则相反。
确认这些都不被违背,以保证至少一个哲学家能够进餐,最终释放出他所使用过的筷子,从而使得更多的哲学家进餐。
采用AND信号量解决:
semaphore chopstick[5]= {1,1,1,1,1};
do{
think;
swait(chopstick[(i+1)%5],chopstick[i]);//等待拿到两只筷子
eat;
ssginal(chopstick[(i+1)% 5],chopstick[i]);//释放两只筷子
}while(TRUE);
3.读者-写者问题
问题:
一个数据对象(数据文件或记录),可以被多个进程共享。其中有些进程要读,有些要写或修改。
允许多个读者进程同时读一个共享对象,但不允许一个写者进程和其它读者或写者进程同时访问共享对象。
解决思路:
1)读进程和写进程之间是互斥的
2)读进程和读进程之间是非互斥的
3)写进程和写进程之间是互斥的
采用信号量集机制解决问题:
//保证多个读,有人写的时候不能读
Reader
Swait(L,1,1 );
Swait( mx,1,0); //有着开关的作用①
Read;
Ssignal(L,1)
//有人读时不能写,并与写互斥
Writer
Swait(mx,1,1;L,RN,0); //②
Write;
Ssignal(mx,1)
① 只要无Write进程进入写操作,mx=1,reader进程就都可以进行读操作,若mx=0,则不可以。
②表示读进程和写进程都没有的时候,Write进程才可以进入临界区