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