文档章节

死锁应用示例

木木情深
 木木情深
发布于 2014/02/14 13:33
字数 718
阅读 30
收藏 0

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特征,从而避免了死锁的发生。


本文转载自:http://www.cnblogs.com/sonic4x/archive/2011/07/05/2098036.html

共有 人打赏支持
木木情深
粉丝 37
博文 189
码字总数 26451
作品 0
广州
程序员
使用select for share,for update的场景及死锁陷阱

SELECT ... FOR SHARE 和 SELECT ... FOR UPDATE语句是innodb事务中的常用语句 for share会给表增加一个is锁,给记录行增加一个s锁,for update会给表增加一个ix锁,给记录行增加一个x锁。 ...

伪善者ql
08/05
0
0
java并发编程——死锁

第一部分:概述 我们用经典的“哲学家进餐”问题来理解死锁的概念。五个哲学家坐在一个圆桌旁,他们一共只有五根筷子(不是五双),每两人中间有一根筷子,他们时而思考,时而吃饭,吃完以后...

isam
2016/05/27
71
2
多线程的死锁

Java线程死锁是一个经典的多线程问题,不同线程在等待根本不可能释放的锁,从而导致任务无法完成。 示例: DealThread.java package com.synchronsized; public class DealThread implement...

IT-Mamba
01/11
5
0
并发问题,锁,怎么处理死锁,脏数据处理

SQL Server死锁总结 1. 死锁原理 根据操作系统中的定义:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。 死锁...

pczhangtl
2014/08/03
0
0
Percona Toolkit 学习(二)(pt-config-diff,pt-deadlock-logger,pt-diskstats)

pt-config-diff 比较mysql配置文件和服务器参数 示例: pt-config-diff /etc/my.cnf h=192.168.53.11 --user=root --password=123456 --socket=/tmp/mysql.sockpt-config-dirr /etc/my.cnf ......

caijyi1
06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

[Hive]JsonSerde使用指南

注意: 重要的是每行必须是一个完整的JSON,一个JSON不能跨越多行,也就是说,serde不会对多行的Json有效。 因为这是由Hadoop处理文件的工作方式决定,文件必须是可拆分的,例如,Hadoop将在...

Mr_yul
18分钟前
0
0
54:mysql修改密码|连接mysql|mysql常用命令

1、mysql修改密码: root用户时mysql的超级管理员,默认mysql的密码是空的,直接可以连接上去的,不过这样不安全; 注释:为了方便的使用mysql,需要把mysql加入到环境变量里; #后续自己输入mys...

芬野de博客
25分钟前
0
0
鼠标单击复制粘贴标签中的内容

<span ref="spanContentOne" id="spanContentOne" style="font-size: 14px;">或许不是最亮眼,总比瞎买强一点</span><!--<input type="button" @click="copyClick('1')" value="复制" />-......

帝子兮
29分钟前
0
0
使用axel多线程疯狂下载

在Linux中比较常见见的下载工具是curl和wget,但是下载比较大的文件两者都不支持多线程, 断点续传的作用不见得能发挥到最大。今天介绍一个axel工具,开启多线程疯狂下载。 安装 Fedora/Cen...

linuxprobe16
31分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部