死锁应用示例

signal(c):若C队列为空,继续原进程,否则唤醒队列第一个等待者,自己进入紧急等待队列尾部。


 


【示例】


生产者-消费者问题(有buffer)


问题描述:(一个仓库可以存放K件物品。生产者每生产一件产品,将产品放入仓库,仓库满了就停止生产。消费者每次从仓库中去一件物品,然后进行消费,仓库空时就停止消费。 

解答: 

管程:buffer=MODULE; 

(假设已实现一基本管程monitor,提供enter,leave,signal,wait等操作)


  notfull,notempty:condition; // notfull控制缓冲区不满,notempty控制缓冲区不空; 

count,in,out: integer;     // count记录共有几件物品,in记录第一个空缓冲区,out记录第一个不空的缓冲区 

buf:array [0..k-1] of item_type; 

define deposit,fetch; 

use monitor.enter,monitor.leave,monitor.wait,monitor.signal;

 

procedure deposit(item); 

  if(count=k) monitor.wait(notfull); 

  buf[in]=item; 

  in:=(in+1) mod k; 

  count++; 

  monitor.signal(notempty); 

procedure fetch:Item_type; 

  if(count=0) monitor.wait(notempty); 

  item=buf[out]; 

  in:=(in+1) mod k; 

  count--; 

  monitor.signal(notfull); 

  return(item); 

count=0; 

in=0; 

out=0; 


进程:producer,consumer; 

producer(生产者进程): 

Item_Type item; 

  while (true) 

  { 

    produce(&item); 

    buffer.enter(); 

    buffer.deposit(item); 

    buffer.leave(); 

  } 


consumer(消费者进程): 

Item_Type item; 

  while (true) 

  { 

    buffer.enter(); 

    item=buffer.fetch(); 

    buffer.leave(); 

    consume(&item); 

  } 

}


【附】有关wait和signal的语言表示


信号量结构使用C语言表示如下:


typedef struct {

    int value;//记录了这个信号量的值 

    struct process *list;//储存正在等待这个信号量的进程 

} semaphore;

wait()信号量部分代码如下:


wait(semaphore *S) {

    S->value--;

    if(S->value < 0) {

        add this process to S->list;

        block();

    }

}

signal()信号量部分代码如下:


signal(semaphore *S) {

    S->value++;

    if(S->value <= 0) {

        remove a process P from S->list;

        wakeup(P);

    }

}

一、The Bounded-Buffer Problem:


full初始化为0,empty初始化为n,mutex为1


do{

    wait(full);

    wait(mutex);

    ...

    //remove an item from buffer to nextc

    ...

    signal(mutex);

    signal(empty);

    ...

    //consume the item in nextc

    ...

} while(TRUE);

二、The Readers-Writers Problem:


wrt初始化为1,readcount初始化为0,mutex为1


写者操作: 


 


do{

    wait(wrt);

    ...

    //writing is performed 

    ...

    signal(wrt);

} while(TRUE);

 


 


读者操作:


do{

    wait(mutex);//确保与signal(mutex)之间的操作不会被其他读者打断

    readcount++;

    if(readcount == 1)

        wait(wrt);

    signal(mutex);

    ...

    //reading is performed

    ...

    wait(mutex);

    readcount--;

    if(readcount == 0)

        signal(wrt);

    signal(mutex);

} while(TRUE);


三、The Dining-Philosophers Problem:


所有的chopstick[5]全部初始化为1


do{

    wait(chopstick[i]);

    wait(chopstick[(i+1)%5]);

    ...

    //eating

    ...

    signal(chopstick[i]);

    signal(chopstick[(i+1)%5]);

    ...

    //thinking

    ...

} while(TRUE);

但是这个解决方案的最大问题在于它会出现死锁。所以我认为应该增加一个信号量mutex,并初始化为1:


do{

    wait(mutex);

    wait(chopstick[i]);

    wait(chopstick[(i+1)%5]);

    signal(mutex);

    ...

    //eating  

    ...

    wait(mutex);

    signal(chopstick[i]);

    signal(chopstick[(i+1)%5]);

    signal(mutex);

    ...

    //thinking  

    ...

} while(TRUE);

这样由于确保了一位哲学家在拿起两只筷子的时间内其他哲学家不可以拿起任何一支筷子,从而破坏了死锁出现需要的四个特征中的Hold And Wait特征,从而避免了死锁的发生。


转载于:https://my.oschina.net/starmier/blog/199838

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值