您的位置:首页 > 其它

操作系统精髓与设计原理--并发性:死锁和饥饿

2016-10-20 18:50 267 查看
死锁原理:

死锁可以被定义成一组竞争系统资源或互相通信的进程间的相互的“永久”阻塞。

当一组进程中的所有进程都在等待一个事件(等待请求资源的释放),而只有在进程集合中的其他阻塞的进程才可以触发该事件,这时就称一组进程死锁。

资源:

资源通常可分为两类:

(1)可重用的:一次只能供一个进程安全的使用,并且不会由于使用而耗尽的资源。进程得到资源单元,后来又释放这些单元,供其它进程再次使用。

可重用资源的例子包括:处理器,I/O通道,主存和辅存,设备以及诸如文件,数据库和信号量之类的数据结构。

(2)可消费的:可消费资源是指可以创建(生产)并且可以销毁(消费)的资源。

可消费资源的例子有中断,信号,消息和I/O缓冲区中的信息。

死锁的条件:

1.互斥:一次只有一个进程可以使用一个资源,其他进程不能访问已分配给其他进程的资源。

2.占有且等待:当一个进程在等待分配得到其他资源时,其继续占有已分配得到的资源。

3.非抢占:不能强行抢占进程中已占有的资源

满足上述三个条件可能会存在死锁,但是只有这三个条件,则不一定产生死锁。

死锁需要的第四个条件:

4.循环等待

存在一个封闭的进程链,使得每个资源至少占有此链中下一个进程所需要的一个资源。

处理死锁的三种方式

预防 检测 避免 

(1)采用某种策略来消除条件1至4中的一个条件的出现来防止死锁。

(2)基于资源分配的当前状态做动态选择来避免死锁

(3)试图检测死锁的存在并且试图从死锁中恢复出来。

//////////////////////////////按照如上的顺序对死锁的处理进行讨论如下//////////////////

(1)死锁预防

分为两类:

1.间接的死锁预防,防止前面列出的三个必要条件中任何一个的发生。

2.直接的死锁预防,防止循环等待的发生。

对三个必要条件

互斥:不可能禁止。

占有且等待

措施:一次性的请求所有需要的资源,并且阻塞这个进程直到所有请求都同时满足。

缺点:

(1)一个进程可能被阻塞很长时间以等待满足其所有的资源请求

(2)分配给一个进程的资源可能有相当长的一段时间处于不可用状态,在此期间,它们不能被其他进程使用。另一个问题是一个进程可能事先并不会知道它所需要的所有资源。

非抢占

(1)如果占有某些资源的一个进程进行进一步资源请求被拒绝,则该进程必须释放它最初占用的资源,如果有必要可再次请求这些资源和另外的资源。

(2)如果一个进程请求当前被另一个进程占有的一个资源,则操作系统可以抢占另一个进程要求他释放资源。

循环等待

措施:

通过定义资源类型的线性顺序来预防。如果一个进程已经分配到了R类型资源,那么它接下来请求的资源只能是那些排在R类型之后的资源类型。

(2)死锁避免

死锁预防:通过约束资源请求,防止4个死锁条件中至少一个的发生,这可以通过防止放生三个必要策略条件中的一个(互斥,占有且等待,非抢占)间接完成也可以通过防止预防等待直接完成,但这都会导致低效的资源使用和低效的进程执行。

死锁避免:它允许三个必要条件,但是通过明智的选择,确保永远不会到达死锁点,因此死锁避免比死锁预防允许更多的并发。

死锁避免需要知道将来的进程资源请求的情况。

1.如果一个进程的请求会导致死锁那就不启动此进程。

2.如果一个进程增加资源的请求会导致死锁,则不允许此分配。

对于1.:

如果一个新进程的资源需求会导致死锁,则拒绝这个新进程。

资源分配拒绝(银行家算法)这个蛮重要的,我没详细写是因为我知道,如果不清楚的最好看一看

安全状态:至少有一个进程执行序列不会导致死锁

不安全状态:不安全的一个状态

综合的死锁策略:

在不同情况下使用不同的策略去解决死锁

UNIX的并发机制:

(1)管道(2)消息(3)共享存储区(4)信号量(5)信号

管道,消息和共享存储区提供了进程间传递数据的方法

而信号量和信号则用于其他进程的触发行为

管道:环形缓冲区

允许两个进程以生产者/消费者的模型进行通信,因此这是一个先进先出队列,由一个进程写,而另一个进程读。

无名管道:有亲缘关系的进程

有名管道:都可以

消息:有类型的一段文本

共享存储区:进程间同信速度最快的形式,每个进程有一个只读或都写的权限。互斥约束不属于共享存储区机制的一部分,但必须由使用共享存储区的进程提供。

信号量:以集合的形式创建的

(1)信号量当前的值

(2)在信号量上操作的最后一个进程的进程ID

(3)等待该信号量的值大于当前值得进程数

(4)等待该信号量的值为0的进程数

信号

用于通知发生一个进程同步事件的软件机制。

原子操作

避免简单的竞争条件,原子操作的执行不会被打断或被干涉。

自旋锁

保护临界区,同一时刻只有一个线程能获得自旋锁。

其他企图获得自旋锁的任何线程将一直进行尝试,直到获得了该锁。

自旋锁建立在内存区的一个整数上,任何线程进入临界区之前都必须检查该整数。

如果该值是0,则线程设置该值为1,然后进入临界区。如果该值非0,则该线程继续检查该值,直到它为0.

缺点:锁外面的线程以忙等待(线程在进入代码不断循环)的方式继续执行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: