操作系统第三章经典进程同步与互斥问题

1.设有一缓冲池P,P中含有20个可用缓冲区,一个输入进程将外部数据读入P,另有一个输出进程将P中数据取出并输出。若讲程每次操作均以一个缓冲区为单位,试用记录型信号量写出两个进程的同步算法,要求写出信号量的初值。

semaphore mutex=1;
semaphore full=0;
semaphore empty=20;
int item;
int p[20];
void procedure(){
int i=0;
while(true){
wait(mutex);
wait(empty);
p[i]=item;
i=(i+1)mod 20;
signal(full);
signal(mutex);
}
}
void consume(){
int i=0;
while(true}{
wait(mutex);
wait(full);
item=p[i];
i=(i+1)mod 20;
signal(empty);
signal(mutex);
}
}

下面我们来看看这个代码出现的问题:
问题一:
考虑一种情况,当empty为0的时候,这个时候如果procedure()程序抢占了mutex,但她会时钟在empty那里无线等待;因为她抢占了mutex使得consume()无法执行,这个时候两个程序都会在各自位置无限等待,最后就是个死循环。

而这个问题的出处就在于我们没有搞清楚 full empty mutex这几个信号量各自的角色
我们可以这样理解:full empty是为了判断这个函数有没有资格去执行他的任务;mutex是在判断好有资格的情况下给这个函数以权力,告诉他可以安全的操作共享数据

修改代码如下:

semaphore full=0;
semaphore empty=20;
semaphore mutex=1;
item itema,itemb;
int out,in;
int p[20];
void procedure(){
procedure product itema;
while(true){
wait(empty);
wait(mutex);
p[in]=itema;
in=(in+1)mod 20;
signal(mutex);
signal(full);
}
}
void consume(){
while(true){
wait(full);
wait(mutex);
itemb=p[out];
out=(out+1)mod 20;
signal(mutex);
signal(empty);
consumer product itemb;
}
}

上面那个就是个类生产者问题

2.读写问题(要求:1,允许多个读进程2.读写互斥3写写互斥)

semaphore Wmutex=1,Rmutex=1;
int count;
void Rread(){
while(true){
wait(Rmutex);
if(count==0) wait(Wmutex);
count=count+1;
signal(Rmutex);
read....
wait(Rmutex);
count=count-1;
if(count==0)signal(Wmutex);
signal(Rmutex);
}
}
 void Write(){
 while(true){
 wait(Wmutex);
 write...
 signal(Wmutex);
 }
 }

来思考一下这里面的逻辑:明明读者进程互不互斥,为什么要加一个Rmutex呢?这里的Rmutex就好比是进门,进门一定是一个一个的进来。且我一定呀记录最开始进来的那个人

我们来换种写法看看

semaphore Rmutex=1,Wmutex=1;
void Read(){
while(true){
wait(Wmutex);
read...
signal(Wmutex);
}
}
void Write(){
while(true){
wait(Wmutex);
write..;
signal(Wmutex);
}
}

可以看出,这个程序写的不仅写写互斥,读写互斥,连读读都是互斥的。
可是要保证读读不互斥,read前后就不该有锁,但没有锁,读写就不能互斥了。把count考虑进来,读写是写和第一个读互斥的。

3.哲学家进餐问题

semaphore cho[5]={1,1,1,1,1};
void philoserpher(){
wait(cho[i]);
wait(cho[(i+1)mod5]);
eat;
signal(cho[i]);
signal(cho[(i+1)mod 5]);
think;

没有死锁的哲学家进餐问题

semaphore cho[5]={1,1,1,1,1};
void philoserpher(){
Swait(cho[i],cho[(i+1)mod 5]);

eat;

Ssignal(cho[i],cho[(i+1)mod 5]);

理发师问题(1.n把等待椅子2.没哟顾客,则理发师睡觉3.理发师理发,则顾客等待4.没有椅子则去别家店)


```php
semaphore customer=0;
 semaphore barbner=1;
 semaphore mutex=1;
 semaphre waiting;
 void barbner(){
 while(true){
 wait(customer);
 wait(mutex);
 wait--;
 wait(barbner);
 signal(muteX);
 理发;
 signal(barber);
 }
 }
 void customer()
 {
 wait(mutex);
if(waiting<N){
waiting++;
signal(customer);
signal(mutex);
wait(barbner);
理发;
signal(barber);
}

}
else
signal(mutex);
}


版权声明:本文为weixin_43984457原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。