设有如下两个进程PA和PB,PA进程把n值加1,PB进程打印n值,n的初值为0,现PA和
PB两进程开发执行,要求打印出1,2,3......的连续数.
val:s1.s2:semapior;
s1=1,s2=0
PA:begin                  PB:begin
     repeat                    repeat
       p(s1)                     p(s2)
       n=n+1                     write(n)
       v(s1)                     v(s2)
     until false               until false
   end                       end问:1.上列用P,V操作表示的同步操作算法有何错误?
   2.用P,V操作写出正确的同步算法.

解决方案 »

  1.   

    如果要求按1,2,3,...的顺序打印的话,那就是一个同步问题,由于不能同时访问n,这就还有一个互斥问题:sm = 0;  //用于同步
    mutex = 1; //用于互斥pa:
      p(mutex);
      n = n + 1
      v(mutex);
      v(sm)pb:
      p(sm);
      p(mutex)
      write(n)
      v(mutex)不知道这样对不对,呵呵
      

  2.   

    哦,看来用一个sm还不能实现1,2,3,...这样严格的顺序,那就用两个sm吧:sm_write = 1; //能否写n
    sm_read  = 0; //能否读n
    mutex    = 1; //用于互斥pa:
      p(sm_write);
      p(mutex);
      n = n + 1;
      v(mutex);
      v(sm_read);pb:
      p(sm_read);
      p(mutex);
      write(n);
      v(mutex);
      v(sm_write);呵呵,现在可以精确同步了吧
      

  3.   

    Kidsheep(Kidsheep) , 就是说,应该改成:val:s1.s2:semapior;
    s1=1;// 互斥
    s2=0;// 同步
    PA:begin                  PB:begin
         repeat                    repeat
           p(s1)                     p(s2)
           n=n+1                     p(s1)
           v(s1)                     write(n) 
           v(s2)                     v(s1)
         until false               until false
       end                       end
      

  4.   

    两边分别维护一个信号量,彼此一点关系都没有,怎么可能实现同步呢?我想应该这样:
    val:s1.s2:semapior;
    s1=1,s2=0
    PA:begin                  PB:begin
         repeat                    repeat
           p(s1)                     p(s2)
           n=n+1                     write(n)
           v(s2)                     v(s1)
         until false               until false
       end                       end
      

  5.   

    steedhorse(晨星) ,那这么说就只用S1和S2就可以完全实现同步和互斥的判断了是吗?
      

  6.   

    刚才去看了一下操作系统的书,原来这是经典的同步问题啊,看来不需要互斥了,所以 steedhorse(晨星) 的方法是正确的,不过,如果n是一个缓冲区的话,像这样int n[N],那就要用一个mutex来互斥了,这时sm_write = N, sm_read = 0;