目录
进程间通信介绍(一)
进程同步与进程互斥
一些概念:
//1.临界资源(critical resource):
//系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源(或互斥资源)。
//2.临界区(互斥区)(critical section(region)):
//各个进程中对某个临界资源(互斥资源)实施操作的程序片段。
//3.进程互斥(mutual exclusive):
//由于各进程要求使用共享资源(变量、文件等),而这些资源需要排他性使用,因此各进程之间竞争使用这些资源,这一关系称为进程互斥。
//4.进程同步(synchronization):
//指系统中多个进程中发生的事件存在某种时序关系,需要相互合作,共同完成一项任务。具体地说,一个进程运行到某一点时,要求另一伙伴进程为它提供消息,在未获得消息之前,该进程进入阻塞态,获得消息后被唤醒进入就绪态。
顺序程序与并发程序特征
顺序程序特征 | 并发程序特征 |
顺序性 | 共享性 |
封闭性:(运行环境的封闭性) | 并发性 |
确定性 | 随机性 |
可再现性 |
进程互斥
1、由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程互斥
2、系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源。
3、在进程中涉及到互斥资源的程序段叫临界区
进程同步
进程同步指的是多个进程需要相互配合共同完成一项任务。
P1和P2进程是互相配合的,
只有当P2关门后,P1才能启动车辆;P1正常运行了,P2开始售票;当P1到站停车后,P2才能开门;
即需要互相等待对方完成某个操作,自身才能继续运行下去。
进程间通信目的
1、数据传输:一个进程需要将它的数据发送给另一个进程
2、资源共享:多个进程之间共享同样的资源。
3、通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
4、进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。
进程间通信发展
UNIX进程间通信方式包含:管道、FIFO、信号。
System V进程间通信方式包含:System V消息队列、System V信号灯、System V共享内存
POSIX进程间通信包含:posix消息队列、posix信号灯、posix共享内存。posix互斥量,posix条件变量,posix读写锁
进程间通信分类
- 文件
- 文件锁
- 管道(pipe)和命名管道(FIFO)
- 信号(signal)
- 消息队列
- 共享内存
- 信号量
- 互斥量
- 条件变量
- 读写锁
- 套接字(socket)
需要注意的是,消息队列、共享内存和信号量在System V 和 POSIX 标准中都有定义,而互斥量、条件变量和读写锁只在POSIX标准才有定义。
进程间共享信息的三种方式
文件系统,内核中的共享信息,共享内存区
IPC对象的持续性
1、随进程持续:一直存在直到打开的最后一个进程结束。(如pipe和FIFO)
2、随内核持续( kernel persistence):一直存在直到内核自举或显式删除(如System V消息队列、共享内存、信号量)
3、随文件系统持续:一直存在直到显式删除,即使内核自举还存在。(POSIX消息队列、共享内存、信号量使用文件系统tmpfs 来实现)
进程间通信介绍(二)
死锁
(1)概念
死锁是指多个进程之间相互等待对方的资源,而在得到对方资源之前又不释放自己的资源,这样,造成循环等待的一种现象。如果所有进程都在等待一个不可能发生的事,则进程就死锁了。
(2)死锁产生的必要条件:
1)互斥条件
进程对资源进行排它性使用,即在一段时间内某资源仅为一个进程所占用。
2)请求和保持条件
当进程因请求资源而阻塞时,对已获得的资源保持不放。
3)不可剥夺条件
进程已获得的资源在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4)环路等待条件
各个进程组成封闭的环形链,每个进程都等待下一个进程所占用的资源
(3)防止死锁的办法
资源一次性分配:(破坏请求和保持条件)
可剥夺资源: (破坏不可剥夺条件)
资源有序分配法:(破坏循环等待条件)
(4)死锁避免
预防死锁的几种策略,会严重地损害系统性能。
因此在避免死锁时,要施加较弱的限制,从而获得较满意的系统性能。
由于在避免死锁的策略中,允许进程动态地申请资源。
因而,系统在进行资源分配之前预先计算资源分配的安全性。
若此次分配不会导致系统进入不安全状态,则将资源分配给进程;否则,进程等待。
其中最具有代表性的避免死锁算法是银行家算法。
(5)银行家算法
为保证资金的安全,银行家规定:
- * 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;
- * 顾客可以分期贷款,但贷款的总数不能超过最大需求量
- * 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客贷款可推迟支付,但总能使顾客在有限的时间得到贷款
- * 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金.
(6)哲学家就餐问题
五个哲学家围在一个圆桌就餐,每个人都必须拿起两根筷子才能用餐,当每个人都先拿起左筷子,等待右筷子的时候就会造成死锁。
哲学家就餐问题解法
服务生解法
最多4个哲学家
仅当一个哲学家两边筷子都可用时才允许他拿筷子
给所有哲学家编号,奇数号的哲学家必须首先拿左边的筷子,偶数号的哲学家则反之
信号量和PV原语
(1)信号量 (灯)(主要解决互斥和同步问题)
信号量和P、V原语由Dijkstra(迪杰斯特拉)提出
信号量
互斥:P、V在同一个进程中
同步:P、V在不同进程中
信号量值含义
S>0:S表示可用资源的个数
S=0:表示无可用资源,等待进程
S<0:|S|表示等待队列中进程个数
信号量数据结构
struct semaphore
{
int value; //信号量值
pointer_PCB queue; //等待队列 (进程控制块指针,表示当前那些进程处于等待状态)
};
(2)P原语伪代码 (使用资源 -1)
P(s){
s.value--; //信号量计数值减一
if (s.value < 0){ //先前<=0 意味无资源可用 如果有新进程申请资源,就将该进程设置为等待状态,插入相应等待队列
//该进程状态置为等待状状态
//将该进程的PCB指针插入相应的等待队列s.queue末尾
}
}
///注意,PV 操作都是原子性操作,要么全部执行要么全部不执行,在阻塞后返回也算是完成一个流程,但如果设置了IPC_NOWAIT选项,当资源暂且不可用时直接返回错误,此时对信号量的操作都没有执行。
(3)V原语伪代码 (释放资源+1)
V(s){
s.value++;
if (s.value < =0){
//唤醒相应等待队列s.queue中等待的一个进程
//改变其状态为就绪态
//并将其插入就绪队列
}
}
(4)用PV原语解决司机与售票员问题
(5)用PV原语解决民航售票问题
(6)用PV原语解决汽车租赁问题
有一汽车租赁公司有两部敞篷车可以出租,假定同时来了四个顾客都要租敞篷车,那么肯定会有两 个人租不到。