操作系统经典同步问题

经典同步问题

一、 生产者—消费者问题

分析:

(1)无论生产者、消费者使用缓冲池时应保证互斥使用(互斥信号量mutex )
(2)生产者和消费者间交叉有序:
a.有序的控制最根源在产品数量上。
b.设置两个信号量:
分别针对生产者、消费者设置不同的信号量,empty和full分别表示缓冲池中空缓冲池和满缓冲池(即产品)的数量。

生产者:

repeat
produce an item in nexp;

wait(empty);
wait(mutex);


buffer(in):=nexp;
in:=(in+1) mod n;

signal(mutex);
signal(full);


until  false; 

消费者:

repeat

wait(full);
wait(mutex);

nextc:=buffer(out);
out:=(out+1) mod n;

signal(mutex);
signal(empty);

consume the item in nexc;                        
until  false;   

总结:

1.每个程序中用于实现互斥的wait(mutex)和signal(mutex)必须成对地出现。
2.控制顺序的信号量empty和full的wait和signal操作,成对地出现在不同的进程中
3.在每个程序中的多个wait操作顺序不能颠倒。且应先执行对资源信号量的wait操作,再执行对互斥信号量的wait操作,否则可能引起进程死锁。
4.模拟交替执行过程,检查控制是否正确。

二、哲学家就餐问题

方法一:至多只允许有四位哲学家同时去拿左边的筷子,最终能保证至少有一位哲学家能够进餐,并在用毕后释放出他用过的两只筷子,从而使更多的哲学家能够进餐。

semaphore kuaizi[5]={1,1,1,1,1};
semaphore r=4;
void philosopher(int i)
{
    while(true)
    {
        think();
        wait(r);//请求进餐
        wait(kuaizi[i]);//请求左手边的筷子
        wait(kuaizi[(i+1)mod 5]);//请求右手边的筷子
        eat();
        signal(kuaizi[(i+1)mod 5]);//释放右手边的筷子
        signal(kuaizi[i]);//释放左手边的筷子
        signal(r);//释放信号量r
        think();
    }
}

方法二:仅当哲学家的左右两只筷子均可用时,才允许他拿起筷子进餐。—采用AND信号量。

semaphore kuaizi[5]={1,1,1,1,1};
void philosopher(int i)
{
    while(true)
    {
        think();
        wait(kuaizi[i];kuaizi[(i+1)mod 5]);
        eat();
        signal(kuaizi[(i+1)mod 5];kuaizi[i]);
        think();
    }
}

方法三:奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子;偶数号哲学家则相反。

semaphore kuaizi[5]={1,1,1,1,1};
void philosopher(int i)
{
    while(true)
    {
        if(i mod 2==0)
        {
            wait(kuaizi[(i+1)mod 5]);
            wait(kuaizi[i]);
            eat();
            signal(kuaizi[i]);
            signal(kuaizi[(i+1)mod 5]);
        }
        else
        {
            wait(kuaizi[i]);
            wait(kuaizi[(i+1)mod 5]);
            eat();
            signal(kuaizi[(i+1)mod 5]); 
            signal(kuaizi[i]);
        }

    }
}

三、读写者问题

分析:
1、一个数据文件被多个进程共享。Reader进程只要求读文件,Writer进程要求写入内容。
2、合理的同步关系是:多个读进程可同时读;Writer进程与任何其他进程(包括Reader进程或其他Writer进程)不允许同时访问文件。

读者:

begin
repeat
   
   wait(rmutex);
   if Readcount=0
      then  wait(wmutex);
   Readcount :=Readcount +1;
   signal(rmutex);
   …
   perform read operation;
   …
   wait(rmutex);
   Readcount :=Readcount -1;
   if Readcount=0
      then  signal(wmutex);
   signal(rmutex);
until  false;
end

写者:
写者操作要和其他的都互斥,所以必要判断互斥信号量。
只有第一个读进程进行互斥判断;只要有一个“读进程”在读就不释放,“写进程”就不能写。(一种读者优先的方式)

repeat
   wait(wmutex);
   写入文件;
   signal(wmutex);
until  false;

你可能感兴趣的:(操作系统经典同步问题)