您的位置:首页 > 其它

操作系统--进程管理--进程同步的经典问题

2014-07-15 19:17 465 查看

哲学家进餐问题:

    由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题。该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐完毕,放下筷子继续思考。

利用AND 信号量机制解决哲学家进餐问题:

    在哲学家进餐问题中,要求每个哲学家先获得两个临界资源(筷子)后方能进餐,这在本质上就是前面所介绍的AND 同步问题,故用AND 信号量机制可获得最简洁的解法。描述如下:

Var chopsiick array of semaphore:=(1,1,1,1,1);
processi
repeat
think;
Sswait(chopstick[(i+1)mod 5],chopstick[i]);
eat;
Ssignat(chopstick[(i+1)mod 5],chopstick[i]);
until false;


读者--写者问题:

    一个数据文件或记录,可被多个进程共享,我们把只要求读该文件的进程称为“Reader进程”,其他进程则称为“Writer 进程”。允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱。但不允许一个Writer 进程和其他Reader 进程或Writer 进程同时访问共享对象,因为这种访问将会引起混乱。所谓“读者—写者问题(Reader-Writer Problem)”是指保证一个Writer 进程必须与其他进程互斥地访问共享对象的同步问题。读者—写者问题常被用来测试新同步原语。

利用信号量集机制解决读者—写者问题

    这里的读者—写者问题与前面的略有不同,它增加了一个限制,即最多只允许RN个读者同时读。为此,又引入了一个信号量L,并赋予其初值为RN,通过执行wait(L,1,1)操作,来控制读者的数目。每当有一个读者进入时,就要先执行wait(L,1,1)操作,使L的值减1。当有RN 个读者进入读后,L 便减为0,第RN+1 个读者要进入读时,必然会因wait(L,1,1)操作失败而阻塞。对利用信号量集来解决读者—写者问题的描述如下:

Var RN integer;
L,mx: semaphore:=RN,1;

begin
parbegin
reader: begin
repeat
Swait(L,1,1);
Swait(mx,1,0);
...
perform read operation;
...
Ssignal(L,1);
until false;
end

writer: begin
repeat
Swait(mx,1,1;L,RN,0);
perform write operation;
Ssignal(mx,1);
until false;
end
parend
end

    其中,Swait(mx,1,0)语句起着开关的作用。只要无writer 进程进入写,mx=1,reader 进程就都可以进入读。但只要一旦有writer 进程进入写时,其mx=0,则任何reader 进程就都无法进入读。Swait(mx,1,1;L,RN,0)语句表示仅当既无writer 进程在写(mx=1),又无reader 进程在读(L=RN)时,writer 进程才能进入临界区写。

生产者--消费者

利用AND 信号量解决生产者—消费者问题:

    对于生产者—消费者问题,也可利用AND 信号量来解决,即用Swait(empty,mutex)来代替wait(empty)和wait(mutex);用Ssignal(mutex,full)来代替signal(mutex)和signal(full);用Swait(full,mutex)来代替wait(full)和wait(mutex),以及用Ssignal(mutex,empty)代替Signal(mutex)和Signal(empty)。利用AND 信号量来解决生产者—消费者问题的算法描述如下:

Var mutex,empty,full: semaphore:=1,n,0;
buffer:array[0,…,n-1] of item;
in out: integer:=0,0;

begin
parbegin
producer: begin
repeat
<pre name="code" class="plain">
...
produce an item in nextp;
...
Swait(empty,mutex);
buffer(in):=nextp;
in:=(in+1)mod n;
Ssignal(mutex,full);
until false;
end
consumer:begin
repeat
Swait(full,mutex);
Nextc:=buffer(out);
Out:=(out+1) mod n;
Ssignal(mutex,empty);
consumer the item in nextc;
until false;
end
parend
end


利用管程解决生产者—消费者问题:

    在利用管程方法来解决生产者—消费者问题时,首先便是为它们建立一个管程,并命名为ProclucerConsumer,或简称为PC。其中包括两个过程:    (1) put(item)过程。生产者利用该过程将自己生产的产品投放到缓冲池中,并用整型变量count 来表示在缓冲池中已有的产品数目,当count≥n 时,表示缓冲池已满,生产者须等待。    (2) get(item)过程。消费者利用该过程从缓冲池中取出一个产品,当count≤0 时,表示缓冲池中已无可取用的产品,消费者应等待。    PC管程可描述如下:

type producer-consumer=monitor

Var in,out,count: integer;
buffer: array[0, …, n-1] of item;
notfull,notempty:condition;

procedure entry put(item)
begin
if count>=n then notfull.wait;
buffer(in):=nextp;
in:=(in+1) mod n;
count:=count+1;
if notempty.queue then notempty.signal;
end

procedure entry get(item)
begin
if count<=0 then notempty.wait;
nextc:=buffer(out);
out:=(out+1) mod n;
count:=count-1;
if notfull.quene then notfull.signal;
end

begin
in:=out:=0;
count:=0
end


在利用管程解决生产者—消费者问题时,其中的生产者和消费者可描述为:

producer: begin
repeat
produce an item in nextp;
PC.put(item);
until false;
end
consumer: begin
repeat
PC.get(item);
consume the item in nextc;
until false;
end


具体的再详细百度。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: