4.1.进程通信
4.1.1.概述
在一个进程调用另一个进程时,进程间需要进行通信。在管理进程时,需要与进程进行通信。
4.1.2.管道通信
Windows采用匿名管道技术进行进程间通信。匿名管道通信只支持具有亲缘关系的进程之间通信(父进程、子进程、兄弟进程)。管道是单向的,由写的一方建立,一头写一头读,若要双向通信,需要两条管道。Windows并不是只支持父子进程之间通信,因为Windows并不是只使用了匿名管道技术来支撑底层间进程的通信。
4.1.3.信号通信
Linux使用信号进行进程间通信,信号是向进程发送的一个通知,通知该事件已经发生,收到信号后进程做出相应的操作,信号可以由硬件产生,也可以由进程产生。
Ctrl+C快捷键,产生SIGINT信号,杀死当前进程。
Ctrl+Z快捷键,产生SIGTSTP信号,挂起当前进程。
kill -9命令,产生SIGKILL信号,杀死一个进程。
调用kill()函数,产生SIGKILL信号,杀死一个进程。
硬件异常或内核异常,产生信号。
……
Linux中定义了64种信号,常用以下几种:
编号 | 名称 | 说明 |
2 | SIGINT | 结束进程,Ctrl+C快捷键,产生SIGINT信号 |
6 | SIGABRT | 结束进程,调用abort函数产生 |
9 | SIGKILL | 进程强制结束 |
11 | SIGUSR1 | 用户自定义型号1 |
14 | SIGALRM | 定时器时间到 |
19 | SIGTSTP | 进程暂停执行 |
4.2.死锁
4.2.1.概述
两个或者多个进程无限期的等待永远不会发生的条件的一种系统状态,结果是进程永远阻塞。造成死锁的底层原因是进程间相互占有了对方释放锁的条件资源。举个例子就是:
小明想的是——妈妈做好饭我就回家,而小明妈妈想的是——小明回家我就做饭。
此处以三进程间的死锁为例展示一下死锁情况下的相互持有资源的一个状况:
4.2.2.解决策略
根据上图可以看到死锁的产生一定是产生了一个资源相互持有的环路,其实不让环路产生,或者破坏掉环路任意一条边就可以解开死锁。
目前常用的解决策略有:
- 有序资源分配法
- 鸵鸟策略
有序资源分配法:
系统中的每个资源分配一个唯一序号,进程每次申请资源时只能申请序号更大的资源。
鸵鸟策略:
因为解决死锁难度很大,实现很复杂,所以现代操作系统,不论是Linux还是Windows都没有去实现死锁解决策略,全部是留给用户去手动解决。
4.3.进程调度
4.3.1.概述
在合适的时候以一定策略选择一个就绪的进程运行。
进程调度的目标:
响应速度尽可能快
进程的处理时间尽可能短
系统的吞吐量尽可能大
系统资源利用率尽可能高
尽量避免某进程长时间未被调度造成的进程饥饿
进程调度的两种量化衡量指标:
周转时间、平均周转时间。
带权周转时间、平均带权周转时间。
周转时间:进程在系统内停留的时间。
带权周转时间:周转时间/运行时间。是个无单位量纲的数字。
4.3.2.典型调度算法
1.先来先服务算法
先进入系统的作业优先运行。
缺点:没有考虑到作业的长短问题,有可能先来的全是大作业,执行速度很慢,不利于后来的短作业的执行。
2.短作业优先算法
优先执行运行时间短的作业。
缺点:未考虑等待时间,很可能造成先来的大作业一直等待。
3.响应比高者优先算法
计算每个作业的响应比,响应比高的先被执行。
响应比=响应时间/运行时间
=(等待时间+运行时间)/运行时间
=1+等待时间/运行时间
从公式可以看出,如果作业等待时间相同,则运行时间越短的作业,其响应比越高,越容易被调度,因而有利于短作业。如果作业运行时间相同,则等待时间越长的作业,其响应比越高,因此越容易被调度,因此有利于等候长的作业。所以可以看出响应比既考虑到了等待时间又考虑到了运行时间。
4.优先数调度算法
优先调度优先数高的进程。
优先数=静态优先数+动态优先数
静态优先数:进程创建时确定,整个运行期间不再改变。
动态优先数:在运行期间不断调整变化。
决定静态优先数的因素:
所需资源
运行时间的长短
进程的类型
动态优先数变换的触发条件:
使用CPU超过一定时长
进行I/O操作以后
进程等待超过一定时长
5.循环轮转调度算法
把所有就绪进程按照先进先出的原则排成队列,新进来的进程加到队列末尾。进程以时间片q 为单位轮流使用CPU,刚刚运行一个时间片的进程排队到队列末尾,等候下一轮运行。
时间片的大小很关键,过小会造成系统调度过于频繁,增加开销,过大,性能会直接跌落为先来先服务算法。