单 生产者-消费者问题 考虑同步问题
基本制约关系:
1、若缓冲区已满,生产者不可在写入数据
2、若缓冲区为空,消费者不可读出数据
伪代码:
data表示数据的信号量,empty表示缓冲区数目的信号量
使用两个信号量即可实现最简单的同步问题
生产者
产生一个数据;
P(empty);
将数据放入buf;
V(data);
消费者
P(data);
从buf中取数据;
V(empty);
打印;
多 生产者-消费者问题 考虑互斥
仅仅上面的两个明显不够,需要多一个信号量表示互斥:mutex:表示有界缓冲区是否被占用,初始值为1
新的制约关系:
1、多个生产者对一个地址进行写入数据,需要互斥进行
2、多个消费者取同一地址的数据,需要互斥进行
伪代码:
生产者:
产生一个数据;
P(empty);
P(metex);
将数据放入buf;
V(metux);
V(data);
消费者
P(data);
P(metux);
从buf中取数据;
V(metex);
V(empty);
消费;
哲学家就餐问题
来自百度百科
哲学家就餐问题可以这样表述,假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。他们只能使用自己左右手边的那两只餐叉。哲学家就餐问题有时也用米饭和筷子而不是意大利面和餐叉来描述,因为很明显,吃米饭必须用两根筷子。
哲学家从来不交谈,这就很危险,可能产生死锁,每个哲学家都拿着左手的餐叉,永远都在等右边的餐叉(或者相反)。即使没有死锁,也有可能发生资源耗尽。例如,假设规定当哲学家等待另一只餐叉超过五分钟后就放下自己手里的那一只餐叉,并且再等五分钟后进行下一次尝试。这个策略消除了死锁(系统总会进入到下一个状态),但仍然有可能发生“活锁”。如果五位哲学家在完全相同的时刻进入餐厅,并同时拿起左边的餐叉,那么这些哲学家就会等待五分钟,同时放下手中的餐叉,再等五分钟,又同时拿起这些餐叉。
在实际的计算机问题中,缺乏餐叉可以类比为缺乏共享资源。一种常用的计算机技术是资源加锁,用来保证在某个时刻,资源只能被一个程序或一段代码访问。当一个程序想要使用的资源已经被另一个程序锁定,它就等待资源解锁。当多个程序涉及到加锁的资源时,在某些情况下就有可能发生死锁。例如,某个程序需要访问两个文件,当两个这样的程序各锁了一个文件,那它们都在等待对方解锁另一个文件,而这永远不会发生。
解决方法:(死锁预防)
- 允许最多 4 个哲学家同时坐在桌子上。
- 只有一个哲学家的两根筷子都可用时,他才能拿起它们(他必须在临界区内拿起两根 辕子)。
- 使用非对称解决方案。即单号的哲学家先拿起左边的筷子,接着右边的筷子;而双 号的哲学家先拿起右边的筷子,接着左边的筷子。
银行家算法
来自百度百科
在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系
银行家算法
统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。为实现银行家算法,系统必须设置若干数据结构。
安全序列是指一个进程序列{P1,…,Pn}是安全的,即对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。
通过合理分配资源实现 避免死锁
来看一道例题: