1、生产者-消费者问题
问题描述是:有一群生产者进程在生产产品,此产品提供给消费者去消费。为使生产者和消费者进程能并发执行,在它们之间设置一个具有n个缓冲池,生产者进程可将它所生产的产品放入一个缓冲池中,消费者进程可从一个缓冲区取得一个产品消费。
问题分析: 设两个同步信号量:一个说明空缓冲区的数目,用empty表示,初值为有界缓冲区的大小N,另一个说明已用缓冲区的数目,用full表示,初值为0。由于在执行生产活动和消费活动中要对有界缓冲区进行操作。有界缓冲区是一个临界资源,必须互斥使用,所以另外还需要设置一个互斥信号量mutex,其初值为1。
semaphore mutex=1,empty=n,full=0;
item buffer[n]; //缓冲区
int in=out=0; //输入、输出指针
void producer()
{
while(1)
{
…
生产一个产品nextp;
…
wait(empty); //等待空缓冲区的数目非0
wait(mutex); //等待无进程操作缓冲区
buffer[in]= nextp; //往Buffer [in]放产品
in = (in+1) mod n;
signal(mutex); //允许其它进程操作缓冲区
signal(full); //增加已用缓冲区的数目
}
}
void consumer()
{
while(1)
{ ……
wait(full); //等待已用缓冲区的数目非0
wait(mutex); //等待无进程操作缓冲区
nextc = buffer[out]; //从Buffer [out]取产品
out = (out +1) mod n;
signal(mutex); //允许其它进程操作缓冲区
signal(empty); //增加空缓冲区的数目
消费nextc产品;
}
}
main()
{
cobegin{
producer();
consumer();
}
}
}
利用AND信号量解决生产者-消费者问题
semaphore mutex=1,empty=n,full=0;
item buffer[n]; //缓冲区
int in=out=0; //输入、输出指针
void producer()
{
while(1)
{
…
生产一个产品nextp;
…
swait(empty, mutex);
buffer[in]= nextp; //往Buffer [in]放产品
in = (in+1) mod n;
ssignal(mutex, full);
}
}
void consumer()
{
while(1)
{
……
swait(full, mutex);
nextc = buffer[out]; //从Buffer [out]取产品
out = (out +1) mod n;
signal(mutex, empty);
消费nextc产品;
}
}
2、读者-写者问题
问题描述有两组并发进程: 读者(Reader)和写者(Writer),共享一组数据区或一个共享文件; 要求:允许多个Reader同时执行读操作
不允许Reader 、 Writer同时操作
不允许多个Writer同时操作
采用记录型信号量集解决读者-写者问题
如果读者来:
1)无读者、写者,新读者可以读
2)有写者等待,但有其它读者正在读,则新读者也可以读
3)有写者写,新读者等待
如果写者来:
1)无读者,新写者可以写
2)有读者,新写者等待
3)有其它写者,新写者等待
设有两个信号量wmutex=1,rmutex=1
另设一个全局变量readcount =0,表示正在读的读者数目
wmutex用于读者和写者、写者和写者之间的互斥
rmutex用于对readcount 这个临界资源的互斥访问
Var rmutex,wmutext: semaphore :=1,1;
Readcount: integer :=0;
begin
parbegin
Reader:begin
repeat
wait(rmutex); //等待无进程访问readcount
if (readcount=0) wait (wmutex); //等待无写者写
readcount := readcount+1;
signal(rmutex); //允许其它进程访问readcount
读
wait(rmutex); //等待无进程访问readcount
readcount := readcount-1;
if (readcount==0) signal(wmutex); //允许写者写
signal(rmutex); //允许其它进程访问readcount
until false
end
Writer:begin
repeat
wait(wmutex); //等待无写者写,无读者读
写
signal(wmutex); //允许写者写,读者读
until false
end
parend
end
增加一个限制条件:同时读的“读者”最多RN个
mx表示“允许写”,初值是1
L表示“允许读者数目”,初值为RN
Var RN: integer;
L, mx: semaphore :=RN,1;
begin
parbegin
Reader:begin
repeat
Swait(L, 1, 1); //控制读者数目
Swait(mx, 1, 0);//无写者时(mx=1)读者
可读; 有写者时(mx=0), 读者不可读
…
读
…
Ssignal(L, 1);
until false
end
Writer:begin
repeat
Swait(mx,1,1; L,RN,0); //在既无写者写(mx=1) 又无读者读(L=RN)时,新写者可写
写
Ssignal(mx,1); //允许其他读者、写者操作(mx=1)
until false
end
parend
end