制片人/消费者Mesa vs Hoare语义

时间:2013-03-10 16:33:32

标签: c synchronization producer-consumer monitors

我遇到过两种不同的监视器实现。一个使用while循环,它在每次进入睡眠之前检查特定条件是否为真,并且在从睡眠中唤醒时再次检查。另一个只检查if条件是否为真,如果不是则进入休眠状态,但在唤醒时不再检查。我相信前者使用Mesa语义而后者使用Hoare语义。 Wkepedia实现生产者消费者问题(http://en.wikipedia.org/wiki/Producer-consumer_problem#Using_monitors)的方式是使用我相信的Mesa语义。我们如何使用Hoare实现这一目标?

会是这样的吗?

monitor ProducerConsumer{
  int itemCount;
  int nextCount;
  condition full;
  condition empty;
  condition nextSem;

  init(n){
    itemCount = n;
  }

  void add(item){
    wait(mutex);
    if(itemCount == BUFFER_SIZE){
      cwait(full)
    }
    putItemIntoBuffer(item);
    itemCount = itemCount + 1;
    if(itemCount == 1){
      csignal(empty);
    }

    //To give priority to threads already in the monitor over
    //"normal" threads that want to enter the monitor for the 
    //first time.
    if(nextCount>0){
      signal(nextSem);
    }else{
      signal(mutex);
    }
  }

  void consume(){
    wait(mutex);
    if(itemCount == 0){
      cwait(empty);
    }
    item = removeItemFromBuffer();
    itemCount = itemCount - 1;
    if(itemcount == BUFFER_SIZE - 1 ){
      csignal(full);
    }

    //To give priority to threads already in the monitor over
    //"normal" threads that want to enter the monitor for the 
    //first time.
    if(nextCount>0){
      signal(nextSem);
    }else{
      signal(mutex);
    }
  }

  cwait(sem x){
    x.cnt = x.cnt + 1;
    if(nextCount > 0)
      signal(nextSem);
    else
      signal(mutex);
    endif
    wait(x);
    x.cnt = x.cnt - 1;
  }

  csignal(sem x){
    if(x.cnt > 1){
      nextCount = nextCount + 1;
      signal(x);
      wait(nextSem);
      nextCount = nextCount -1;
    }
  }
}

1 个答案:

答案 0 :(得分:0)

我会这样做

monitor ProducerConsumer{
    int BUFFERSIZE ; 
    int itemCount ; // invariant 0 _< itemCount and itemCount _< BUFFERSIZE
    condition notFull; // signalled only if itemCount < BUFFERSIZE
    condition notEmpty; // signalled only if itemCount > 0

    init(n){
        // Assumption. init is called once, before any call to add or remove.
        // precondition n >_ 1
        BUFFERZISE = n ;
        itemCount = 0;
    }

    void add(Item item){
        if(itemCount == BUFFER_SIZE){
            wait(notFull)
        }
        putItemIntoBuffer(item);
        itemCount = itemCount + 1;
        if( ! empty( notEmpty) ) signal(notEmpty);
    }

    Item consume(){
        if(itemCount == 0){
            wait( notEmpty );
        }
        Item item = removeItemFromBuffer();
        itemCount = itemCount - 1;
        if( ! empty(notFull) ) signal(notFull);
        return item ;
    }
}

我假设,因为这是一个监视器,进入和离开监视器是隐式操作。

注意,在信号之后,线程不需要等待。如果语言具有signalAndLeave操作,则可以使用该操作。例如,在Java中,使用我的monitor包,您可以使用

结束add
if( ! notEmpty.isEmpty() ) notEmpty.signalAndLeave( ) ; else leave() ;

您可以使用

结束remove
if( ! notFull.isEmpty() ) return notFull.signalAndLeave(item) else { leave() ; return item ; }