操作系统知识点(七)——信号量

2019-11-09  本文已影响0人  咋家

信号量

背景

信号量(semaphore)

信号量使用

特性
分类
使用
生产者-消费者问题
class BoundedBuffer{
    mutex =new Semaphore(1);
    fullBuffers =new Semaphore(0);
    emptyBuffers =new Semaphore(n);
}
BoundedBuffer::Producter(c){
    emptyBuffers ->P();
    mutex ->P();
    ADD C TO THE BUFFER;
    mutex ->V();
    fullBuffers ->V();
}
BoundedBuffer::Consumer(c){
    fullBuffers ->P();
    mutex ->P();
    REMOVE C FROM BUFFER;
    mutex ->V();
    emptyBuffers ->V();
}

信号量实现

class Semaphore{
    int sem;
    WaitQueue q;
}
Semaphore: P(){
    sem--;
    if(sem<0){
        ADD THIS THREAD t TO q;
        block(q);
    }
}
Semaphore: V(){
    sem++;
    if(sem<=0){
        REMOVE a THREAD t FROM q;
        wakeup(t);
    }
}

管程(Moniter)

class Condition{
    int numWaiting =0;
    WaitQueue q;
}
Condition::Wait(lock){
    numWaiting++;
    ADD this thread t to q;
    release(lock);
    schedule();
    require(lock);
}
Condition::Signal(){
    if(numWaiting >0){
        REMOVE a thread t from q;
        wakeup(t);
        numWaiting--;
    }
}
class BoundedBuffer {
    …
    Lock lock;
    int count = 0;
    Condition notFull, notEmpty;
}
BoundedBuffer::Producter(c) {
    lock->Acquire();
    while (count == n)
        notFull.Wait(&lock);
    Add c to the buffer;
    count++;
    notEmpty.Signal();
    lock->Release();
}
BoundedBuffer::Consumer(c) {
    lock->Acquire();
    while (count == 0)    
      notEmpty.Wait(&lock);
    Remove c from buffer;
    count--;
    notFull.Signal();
    lock->Release();
}

经典同步问题

读者-写者问题
class Writer(){
    P(WriteMutex);
    write;
    V(WriteMutex);
}
class Reader(){
    P(CountMutex);
    if(Rcount ==0)
        P(WriteMutex);
    ++Rcount;
    V(CountMutex);
    
    read;
    
    P(CountMutex);
    --Rcount;
    if(Rcount ==0)
        V(WriteMutex);
    V(CountMutex);
}
AR = 0;   // # of active readers
AW = 0;   // # of active writers
WR = 0;   // # of waiting readers
WW = 0;   // # of waiting writers
Lock lock;
Condition okToRead;
Condition okToWrite;

//读者
Private Database::StartRead() {
    lock.Acquire();
    while ((AW+WW) > 0) {
        WR++;
        okToRead.wait(&lock);
        WR--;
    }
    AR++;
    lock.Release();
}
Private Database::DoneRead() {
    lock.Acquire();
    AR--;
    if (AR ==0 && WW > 0) {
        okToWrite.signal();
    }
    lock.Release();
}
Public Database::Read() {
  //Wait until no writers;
  StartRead(); 
  read database;
  //check out – wake up waiting writers; 
  DoneRead(); 
}

//写者
Private Database::StartRead() {
    lock.Acquire();
    while ((AW+WW) > 0) {
        WR++;
        okToRead.wait(&lock);
        WR--;
    }
    AR++;
    lock.Release();
}
Private Database::DoneRead() {
    lock.Acquire();
    AR--;
    if (AR ==0 && WW > 0) {
        okToWrite.signal();
    }
    lock.Release();
}
Public Database::Read() {
  //Wait until no writers;
  StartRead(); 
  read database;
  //check out – wake up waiting writers; 
  DoneRead(); 
}
哲学家就餐问题

更多精彩,关注“咋家”

上一篇 下一篇

猜你喜欢

热点阅读