文档章节

死锁应用示例

木木情深
 木木情深
发布于 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
Deadlock的一些总结

1.1.1 摘要 在系统设计过程中,系统的稳定性、响应速度和读写速度至关重要,就像12306.cn那样,当然我们可以通过提高系统并发能力来提高系统性能总体性能,但在并发作用下也会出现一些问题,...

长平狐
2012/06/11
112
0
多线程的死锁

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

没有更多内容

加载失败,请刷新页面

加载更多

关于ComponentOne For WinForm 的全新控件 – DataFilter数据切片器(Beta)

概述 数据切片器在电子商务网站上很常见 - 它们可以帮助用户快速过滤所选商品,并且所有过滤选项都可以在一个地方使用,通常包含核心控件类型为:清单,范围栏和单选按钮等。在ComponentOne ...

葡萄城技术团队
2分钟前
0
0
Spring Data JPA 常见异常

异常一: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception i......

小99
2分钟前
0
0
聊聊flink的EventTime

序 本文主要研究一下flink的EventTime SourceFunction flink-streaming-java_2.11-1.7.0-sources.jar!/org/apache/flink/streaming/api/functions/source/SourceFunction.java /** * Inte......

go4it
15分钟前
1
0
如何解决 homebrew 更新慢的问题

之前一直困扰于 Homebrew 的更新速度,曾试过修改更新源(清华、中科大等)的方式,但是并没什么卵用;也试过设置 curl 代理的方式,但是 brew 走的好像不是 curl 的方式,所以也没用。 通过...

whoru
20分钟前
2
0
TiDB EcoSystem Tools 原理解读系列(二)TiDB-Lightning Toolset 介绍

简介 TiDB-Lightning Toolset 是一套快速全量导入 SQL dump 文件到 TiDB 集群的工具集,自 2.1.0 版本起随 TiDB 发布,速度可达到传统执行 SQL 导入方式的至少 3 倍、大约每小时 100 GB,适合...

TiDB
22分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部