信号量的应用

利用信号量实现进程互斥
semaphore mutex=1;
Pa(){
    while(1){
         wait(mutex);
         临界区;
         signal(mutex);
         剩余区;
     }
}    

Pb(){
    while(1){
         wait(mutex);
         临界区;
         signal(mutex);
         剩余区;
     }
}    


利用信号量实现前驱关系

 //s1->s2(a),s1->s3(b),s2->s4(c),s2->s5(d),s3->s6(e),s4->s6(f),s5->s6(g)

//s1~s6表示六条语句的前驱关系
p1(){s1; signal(a);signal(b);}

p2(){wait(a);s2; signal(c);signal(d);}

p3(){wait(b);s3;signal(e);}
p4(){wait(c);s4; signal(f);}
p5(){wait(d);s5;signal(g);}
p6(){ wait(e); wait(f);wait(g);s6;}
    
void main{
   semaphore a,b,c,d,e,f,g;
   a.value=b.value=c.value=d.value=e.value=f.value=g.value=0;
   cobegin
       p1();p2();p3();p4();p5();p6();
   coend
}


生产者-消费者问题

假定生产者和消费者之间的公用缓冲池有n个缓冲区,利用mutex实现诸进程对缓冲池的互斥使用;利用信号量empty,full分别表示缓冲池的空缓冲区和满缓冲区的数量(缓冲区空闲的数量和生产的物品的数量)。又假定只要缓冲区未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池取走一个消息。

描述如下

void proceducer(){
    while(TRUE){
         product an item a;
         . . .
         wait(empty);
         wait(mutex);
         buffer[in]=nextp;
         in=(in+1)%n;  //对缓冲区的位置循环使用
         signal(mutex);
         signal(full);
      }
}


void consumer(){
     while(TRUE){
          wait(full);
          wait(mutex);
          nextc=buffer[out];
          out=(out+1)%n;
          signal(metux);
          signal(empty);
          consume the item in nextc;
          . . .
      }
}


void main(){
    int in,out=0;
    item buffer[n];
    semaphore mutex=1,empty=n,full=0;
    cobegin
        producer();consumer();
    coend
}


哲学家进餐问题

五位哲学家坐在一张圆桌上并且在左右两只筷子之间,桌子上一共有五只筷子用来吃饭,哲学家的生活方式就是,不是吃饭就是思考交替进行。平时一个哲学家思考,饥饿时试图拿取靠近他的左右两只筷子,获得两只筷子才能吃饭,吃饭后继续思考。

philosopher_i(){  //i=1,2,3,4,5 
    do{
         ...   //think
         swait(chopstick[(i+1)%5],chopstick[i]);
         ....  //eat
         signal(chopstick[(i+1)%5],chopstick[i]);
         }while(TRUE)
}
       
void main(){
   semaphore chopstick[5]={1,1,1,1,1} ;
   cobegin
       philosopher_1(); philosopher_2(); philosopher_3(); philosopher_4(); philosopher_5();
    coend
}

AND型信号量能够很好解决哲学家进餐问题,也能有效避免死锁产生(比如五个人同时那一只筷子的僵持状态)


读者写者问题

一个数据文件可以被多个进程共享,把只要求读该文件的进程称为“Reader进程”,其他进程则称为“Write进程”。允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱。但是不允许

一个Writer进程和其他Reader进程或Writer进程同时访问共享对象。 因为这样的访问会引起混乱,所谓的读者-写者问题,是保证Writer进程必须与其他进程互斥的访问共享对象的同步问题。

利用记录型信号量解决

void reader_i(){    //i=1,2,3,....,n,......
   do{
       wait(rmutex);
       if(readercount==0)wait(wmutex);
       readercount++;
       signal(rmutex);
       ....
       perform read operation;
       ....
       wait(rmutex);
       readcount--;
       if(readcount==0)signal(wmutex);
       signal(rmutex);
       }while(TRUE);
}

void writer_i(){  //i=1,2,3,...,n,...
    do{
        wait(wmutex);
        perform write operation;
        signal(rmutex);
        }while(TRUE);
}


void main(){
    semaphore rmutex=1,wmutex=1;
    int readercount=0;  //因为所有的读者进程都能访问修改readercount变量,所以需要设置rmutex来保护
    cobegin 
        reader_1();reader_2();....;reader_n();
        writer_1();writer_2();.....;writer_n();
     coend
}


 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值