操作系统经典同步问题——读者-写者问题和哲学家进餐问题
1.读者-写者问题
问题描述一个数据文件或者记录可以被多个进程共享,我们只要要求读该进程的成为“Reader进程”,其他进程称为“Writer进程”。允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱。但不允许一个Writer进程和其他Reader进程或者Writer进程同时访问共享对象。
简单来描述就是可以同时多个读者一起读但是一旦写者开始写那么读者或者其他写者就不可以再进行访问了。
关于写者
我们发现在这个问题当中,写者是和写者互斥的同时他也是跟读者互斥的所以我们可以知道它是一个对所有都互斥的进程。所以我们对他的操作就简单了我们只需要一个互斥信号量就可以解决这个问题。
我们设置一个互斥信号量Wmutex即可解决这个问题
Writer(){
while(1){
P(Wmutex)
进行写操作
V(Wmutex)
}
}
关于读者
我们发现在这个问题当中读者是和读者同步的但是他是跟写者互斥的。我们在这种情况下设置一个用来记录读者数量的readcount的变量根据读者的数量来进行判读如果读者的数量>0那么这时只可以进行读者的访问写者的访问时不可以的每一次进行对写者的操作时都需要我们先判断readcount的数值。我们同样也为读者设置一个互斥信号量rmutex
Reader(){
while(1){
p(rmutex) //各读进程互斥访问readcount
if(readcount==0) p(Wmutex) //当前没有读者就可以进行写者的操作
readcount++ //读者申请的话需要数量加一
v(rmutex)
读文件... //上面这一部分使得多个读者能够同时访问接下来读进程结束要出来
P(rmutex);//各读进程互斥访问raeadcount
readcount--;//每当一个读进程完成读操作,读者数量-1
if(readcount==0) //当前没有读者就可以进行写者的操作
V(wmutex);//当没有读者,读操作结束后,写进程解锁
V(rmutex);
}
}
2.哲学家进餐问题
5个哲学家共用一张圆桌,分别坐在圆桌的周围5张椅子上,在圆桌上有5个筷子注意是5个不是5双和5个碗。哲学家平时要思考只有饿了才会吃饭。只有它拿到两只筷子才可以吃饭。
mutex[5] = {1,1,1,1,1}; //初始化信号量
philosopher(){
while(1) {
P(mutex[i]); //拿左边的筷子
P(mutex[(i+1)%5]);//拿右边的筷子
进餐...
V(mutex[i]);//放回左边的筷子
V(mutex[(i+1)%5]);//放回右边的筷子
}
}
但是上面会出现死锁的情况当每个哲学家都拿了左边的筷子那么没人能拿到右边的筷子那么就会出现死锁的问题。关于这个问题我们有三种解决方案
(1)最多让4个哲学家同时去拿左边的筷子那么这样肯定会有一个哲学家可以用餐用完餐之后释放筷子其他人也可以正常使用了。
(2)哲学家必须同时可以拿到左右两只筷子时才允许他拿起筷子进餐
(3)给哲学家标记序号,奇数号哲学家拿左边筷子再拿右边筷子而偶数号哲学家则相反。那么按照规定1,2号哲学家竞争1号筷子,3,4号哲学家竞争3号筷子,即所有哲学家都先竞争奇数号筷子再竞争偶数号筷子最终肯定有一个哲学家可以拿到两只筷子进餐。