互斥、同步
并发原理
信号量
管程
消息
生产者/消费者
读者/写者
死锁、饥饿
死锁的条件
- 互斥:一个资源一次只能给一个进程使用。其他进程不能访问已分配给其他进程的资源。
- 占有且等待:一个进程等待其他进程时,继续占有已经分配的资源。
- 不可抢占:不能强行抢占进程已占有的资源。
- 循环等待。
1-3条件是死锁存在的必要条件。加上条件4才是充分必要条件。
处理死锁
- 预防:消除1-4中的1个条件
- 避免:基于资源分配的当前状态做动态选择
- 检测死锁的存在并恢复
死锁预防
- 互斥:不可能禁止
- 占有且等待:进程一次性请求所有资源。低效,需要知道请求的所有资源
- 不可抢占:进程申请资源被拒,则释放占有的资源;或者可以抢占另一个进程要求释放资源,只有资源很容易恢复才实用。
- 循环等待:定义线性顺序资源,分类了R资源,只能申请R之后的资源。
死锁避免
- 如果一个进程的请求会导致死锁,则不启动进程
- 如果一个进程增加的资源请求会导致死锁,则不允许分配。
进程启动拒绝
只有当前运行进程的最大请求量+新进程请求 <= 系统对应资源总量,才启动。
很难最优,假设最坏情况。
资源分配拒绝(银行家算法)
安全状态:指至少有1个资源分配序列不会导致死锁(所有进程都能运行直到结束)
在当前资源下,N个进程是否存在一个可以运行到结束的进程?策略:当进程请求一组资源时,假设同意该请求,从而改变了系统的状态,然后确认其结果是否还处于安全状态。如果是则同意,不是则阻塞。
死锁检测
检测
- 查找1个进程,使可用资源满足该进程的需求,标记该进程。
- 假设同意资源,运行结束释放资源。重复1,没有则终止
- 有未标记的进程则死锁。
恢复
- 取消所有死锁进程
- 回滚死锁进程,重新启动所有进程
- 连续取消死锁进程直到不再存在死锁
- 连续抢占资源直到不在存在死锁
哲学家就餐问题
5个哲学系、5个叉子,吃面需要2个叉子。
信号量解决方案
方案1,先拿起左边的叉子,然后拿右边的叉子。
问题:都拿起左边的叉子,没有右边的叉子,发生饥饿。
方案2,加入服务员,只允许4个哲学家同时进餐。
管程解决方案
如果至少有1吧叉子不可用,那么哲学家就会在条件变量的队列中等待,可让其他哲学家进入管程。
与信号量不同,管程不会发生死锁,同一时刻只有1个进程进入管程。
第一位哲学家进入管程保证了只要拿左边叉子,一定可以拿到右边的叉子。
UNIX并发机制
- 管道(有名、无名)
- 消息
- 共享内存
- 信号量
- 信号
管道
先进先出队列(FIFO),一个进程写,一个进程读。
• 管道在创建时获得一个固定大小的字节数。
• 当1个进程往管道写时,如有足够空间,则立即执行,否则阻塞。
• 一个进程读取字节多于当前管道中的字节,也被阻塞,否则立即执行
• 操作系统强制实施互斥。
包括:命名管道、匿名管道。
消息
共享内存
信号量
信号
信号的传递是通过修改信号要发送到进程所对应的进程表中的一个域来完成。
信号只保存1位,不能对给定类型的信号进行排队。
Linux内核并发机制
原子操作
- 有些体系有对应的汇编指令。
- 其他通过锁住内存总线的方式保证操作原子性。
自旋锁
信号量
屏障
本文探讨了并发控制原理,包括互斥、信号量、管程等机制,并深入讨论了死锁产生的四个必要条件及如何预防、避免和检测死锁。此外,还介绍了UNIX和Linux内核中的并发机制。
478

被折叠的 条评论
为什么被折叠?



