进程间通信基础知识
1.顺序程序与并发程序的特征
1)顺序程序特征:顺序性、封闭性(运行环境的封闭性)、确定性、可再现性。
2)并发程序特征:共享性、并发性、随机性。
2.进程互斥
1)由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源。进程的这种关系称为互斥
2)系统中某些资源一次只允许一个进程使用,这样的资源称为临界资源或互斥资源。
3)在进程中涉及到互斥资源的程序段叫临界区。
3.进程同步
进程同步指的是多个进程需要相互配合共同完成一项任务
4.进程间通信的目的
1)数据传输:一个进程需要将它的数据发送给另一个进程
2)资源共享:多个进程之间共享同样的资源
3)通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(比如子进程结束了要通知父进程)
4)进程控制:有些进程希望完全控制另一个进程的执行(比如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能及时知道它的状态改变。
5.进程间通信的发展
分为三个阶段:
1)管道
2)System V进程间通信
3)POSIX进程间通信
6.进程间通信分类
文件、文件锁、管道(pipe)和有名管道(FIFO)、信号(signal)、消息队列、共享内存、信号量、互斥量、条件变量、读写锁、套接字。
7.System V IPC & POSIX IPC
1)System V IPC:System V 消息队列、System V共享内存、System V信号量
2)POSIX IPC:消息队列、共享内存、信号量、互斥量、条件变量、读写锁
8.IPC对象的持续性
有三种情况
1)随进程持续:一直存在直到打开的最后一个进程结束(如pipe和FIFO)
2)随内核持续:一直存在直到内核自举或显示删除(如System V消息队列、共享内存、信号量)
3)随文件系统持续:一直存在直到显示删除。即使内核自举还存在。(POSIX消息队列、共享内存、信号量如果是使用映射文件来实现)
内核自举:就是重启系统,重新开机。
9.死锁
死锁是指多个进程之间互相等待对方的资源,而在得到对方资源之前又不释放自己的资源。这样,造成了循环等待的一种现象。如果所有的进程都在等一个不可能发生的事,则进程就死锁了。
10.死锁产生的必要条件
1)互斥条件:进程对资源进行排他性使用。(在一段时间内某资源仅为一个进程所占用)
2)请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放
3)不可剥夺条件:进程已获得的资源在未使用完之前,不能被剥夺,只能等自己用完再自己释放
4)环路等待条件:各个进程组成封闭的环形链,每个进程都等待下一个进程所占用的资源
11.防止死锁方法
1)资源一次性分配:破坏请求和保持条件
2)可剥夺资源:破坏不可剥夺条件
3)资源有序分配法:破坏循环等待条件
12.死锁避免
1)预防死锁的几种策略,会严重的损害系统性能。因此在避免死锁时,要施加较弱的限制,从而获得较满意的性能
2)由于在避免死锁的策略中,允许进程动态的申请资源。因而,系统在进行资源分配之前预先计算资源分配的安全性。若此次分配不会导致系统进入不安全的状态,则将资源分配给进程。否则进程等待。代表避免死锁算法就是银行家算法
13.银行家算法
为保证资金的安全,银行家规定:
1)当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客
2)顾客可以分期贷款,但贷款的总数不能超过最大需求量
3)当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可以推迟,但是总能使顾客在有限的时间里得到贷款。
4)当顾客得到贷款所需要的资金时,一定能在有限的时间里归还所有的资金。
14.信号量
信号量和P、V原语由Dijkstra(迪杰斯特拉)提出。
信号量处理互斥时:P、V在同一进程中、
处理同步时:P、V在不同的进程中
15.信号量有点像一个结构体:
struct semaphore
{
int value;
pointer_PCB queue; // 指向进程控制块的队列
}
16.P原语操作伪代码:这个就是申请资源
P(s)
{
s.value = s.value--;
if(s.value < 0)
{
该进程状态置为等待状态
将该进程的PCB插入相应的等待队列s.queue末尾
}
}
17.V原语操作伪代码:这个是释放资源
V(s)
{
s.value = s.value++;
if(s.value <= 0)
{
唤醒相应等待队列s.queue中等待的一个进程,将其状态改为就绪状态。
并将其插入就绪队列
}
}
18.PV原语解决司机和售票员之间的问题:
对司机来说:
s1(0); // 分配一个信号量
while(1)
{
P(s1) // 申请资源,
开车
到站
停车
V(s2)
}
对售票员来说:
s2(0); // 申请一个信号量
while(1)
{
关门
V(s1) // 释放资源,告诉司机可以开车了
售票
P(s2) // 申请资源,必须等车停好,才能开门
开门
}