操作系统信号量

来源:互联网 发布:sql拒绝访问 编辑:程序博客网 时间:2024/05/29 01:55
          本文将针对较为简单的生产者消费者问题,给出利用信号量解决问题的方法。
       生产者:能产生并投放资源的进程     
      消费者:单纯使用(消耗)资源的进程
       问题表述:生产者进程和一消费者进程(设每组有多个进程)通过缓冲区发生联系。
                           生产者进程将生产的产品(数据、消息等统称为产品)送入缓冲区,消费者进程从中取出产品。
                           假定缓冲区共有N 个,不妨把它们设想成一个环形缓冲池。
      

       它们应满足同步条件

    ①任一时刻所有生产者存放产品的单元数不能超过缓冲区的总容量(N)。

    ②所有消费者取出产品的总量不能超过所有生产者当前生产产品的总量。
    

    设缓冲区的编号为0~N-1,in和out分别是生产者进程和消费者进程使用的指针,指向下面可用的缓冲区,初值都是0。

    设置三个信号量

    Full:表示放有产品的缓冲区数,其初值为0。
    Empty:表示可供使用的缓冲区数,其初值为N。
    Mutex:互斥信号量,初值为1,表示各进程互斥进入临界区,保证任何时候只有一个进程使用缓冲区。
   

生产者进程Producer            

   while(TRUE) {           

        P(Empty);      

        P(Mutex);     

      产品送往buffer(in); 

        in=(in+1)mod N;                      

         /*N为模*/                                

        V(Mutex);    

        V(Full);                

   }          



消费者进程Producer            

   while(TRUE) {           

        P(Full);      

        P(Mutex);     

      产品被取走buffer(out); 

        out=(out+1)mod N;                      

         /*N为模*/                                

        V(Mutex);    

        V(Empty);                

   }    


应注意

  ①在每个程序中必须先做P(mutex),后做V(mutex),二者要成对出现。

  ②对同步信号量full和empty的P, V操作同样必须成对出现,但它们分别位于不同的程序中。

  ③无论在生产者进程中还是在消费者进程中,两个 操作的次序不能颠倒 。


较大的疑惑在于③。

当消费者进程中的P(Mutex)操作在先,P(Full)操作在后,若先执行消费者进程,则Mutex-1,为0,且Full为0(一个资源也没有),则无法进入缓冲区获得资源;同时,因为Mutex为0,生产者进程无法进入缓冲区投放资源(无论生产者进程的两个P操作顺序如何),无法投放资源,则消费者进程无法往下执行,故而形成死锁。

当生产者进程中的P(Mutex)操作在先,P(Full)操作在后,消费者进程中的P(Full)操作在先,P(Mutex)操作在后,若生产者进程往缓冲区投放资源,直至投满缓冲区,且之后消费者进程刚完成P(Full)操作,就被生产者抢了CPU,完成了P(Mutex)操作,但此时由于缓冲区已满,故无法再投放资源,而消费者进程则由于生产者进入了临界区,故无法到临界区取资源,也无法继续往下执行,故而形成死锁。

所以无论在生产者进程中还是在消费者进程中,两个 操作的次序不能颠倒 。


原创粉丝点击