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 endWriter:begin repeat wait(wmutex); //等待无写者写,无读者读 写 signal(wmutex); //允许写者写,读者读 until false end parend end增加一个限制条件:同时读的“读者”最多RN个mx表示“允许写”,初值是1
L表示“允许读者数目”,初值为RNVar 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 endWriter:begin repeat Swait(mx,1,1; L,RN,0); //在既无写者写(mx=1) 又无读者读(L=RN)时,新写者可写 写 Ssignal(mx,1); //允许其他读者、写者操作(mx=1) until false end parend end