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版权协议,转载请附上原文出处链接和本声明。