一、进程概念
进程是执行中的程序。它包含:
1、文本段(代码)
2、堆栈段(临时数据,例如函数参数,返回地址和局部变量)
3、数据段(全局变量等)
4、堆(进程运行期间动态分配的内存,例如malloc())
二、进程状态
三、进程操作
1、进程创建
大多数操作系统通过进程标识符来识别进程(pid)
Unix中,系统调用fork()来创建进程。这个系统调用会复制原来的地址空间(父进程的复制),不过一般在fork()后会执行exec()用新程序来取代进程的内存空间。exec()根据指定的文件名找到可执行文件,并用它来取代调用进程的内容。
Windows中,用win32函数CreatProcess来创建进程,而且CreatProcess负责将正确的程序装入新的进程。该系统调用有10个参数用来指明新进程的许多特性。
2、进程终止
完成工作而终止的进程。在UNIX中该调用为exit(),windows中为ExitProcess()。所有进程资源将被释放。
进程出现严重错误(除数是零,引用不存在的内存等)进程会被操作系统中断。
其他进程也可以执行系统调用来杀死某个进程。
四、进程间通信
进程间通信的两种基本模式:共享内存和消息传递
多个进程并发访问和操作同一数据且执行结果与访问发生的特定顺序有关,称谓竞争条件
进程同步
1.临界区问题
有n个进程,每个进程有一段代码可能改变同一个共同变量。则当一个进程进入临界区,没有其他进程可以在临界区内执行。
要求:互斥、前进、有限等待
Peterson算法:
2.锁
闭锁和开锁必须为原子操作(不能被中断)
进入临界区必须获得锁并闭锁,出临界区要开锁
其他持有锁的进程必须等待锁打开才能进入临界区,此前必须等待
3.信号量
我们可以认为信号量是某可用资源的数量(类似停车位),每当有进程进入临界区则信号量减一(wait),离开临界区信号量加一(signal)。信号量的加减也是原子操作。一个进程执行wait()操作是,如果信号量不正,则它必须等待。
忙等:一个进程位于临界区内,其他等待的进程在代码中循环(自旋锁)。虽然避免上下文切换,可是浪费了CPU时钟。可以修改信号量的数据结构加入等待进程链表。
死锁:组内每个进程都等待一个事件,而该事件只能由另一个进程产生。
4.管程
锁加条件变量
五、进程调度
原理:进程执行由CPU执行和I/O等待周期组成,每当CPU空闲时操作系统从就绪队列中选择一个进程执行。
非抢占调度:一单CPU分配给一个进程,该进程会一直使用CPU直到进程终止或切换到等待状态。
1、调度算法的准则
CPU使用率
吞吐量:一个时间单元内完成进程的数量
周转时间:从进程提交到进程完成的时间段,包括等待时间和I/O
等待时间:在就绪队列中等待所花费的时间之和
响应时间:从提交要求到产生响应的第一时间
调度算法需要时CPU使用率和吞吐量最大化,周转时间,等待时间和响应时间最小化。
2、调度算法
1.先到先服务算法(FCFS) 非抢占的
2.最短作业优先调度(SJF)
困难在于如何知道下一个CUP区间的长度,短期CPU调度上不能实现。可以根据历史记录预测CPU区间长度的近似值。
抢占的SJF算法称谓最短剩余时间优先调度
3.优先级调度
问题:无穷阻塞或者饿死现象 某个低优先级的进程可能无线等待CPU从而无法运行
解决方案:老化(aging) 逐渐增加系统中等待时间很长的进程的优先级
4.轮转法调度(RR)
按照时间片进行FCFS算法
如果时间片太小,则会浪费大部分时间在上下文切换上。根据经验,80%的CPU区间应小于时间片。
5.多级队列调度
一个进程被永久分配给一个队列,队列调度通常采用优先级调度
每个队列有自己的调度算法
6.多级反馈队列调度
与上面的调度算法相比,多级反馈队列调度允许进程在队列中移动。如果进程使用过多的CPU时间,它会被转移到更低优先级队列,在较低优先级队列中等待时间过长的进程会被移动到更高优先级队列。
3、多处理器调度
非对称多处理:让一个处理器处理所有的调度决定,I/O处理以及其他系统活动,其他的执行用户代码。
对称多处理(SMP):所有进程可能处于一个共同的就绪队列中或者每个处理器有自己的私有就绪进程队列
处理器亲和性:绝大多数SMP系统试图避免将一个进程从一个处理器移动至另一个处理器,而是努力是一个进程在一个处理器运行。
负载平衡(与亲和性有冲突)
六、死锁
1、死锁特征
必要条件:
互斥:至少有一个资源处于非共享模式,即一次只有一个进程可以使用。
占有并等待:一个进程必须占有至少一个资源,并等待另一个资源,而该资源被其他进程占有。
非抢占:资源不能被抢占,只能在进程完成任务后释放。
循环等待:P0等待的资源P1占有,P1等待的资源P2占有,……,Pn等待的资源P0占有。
2、死锁预防
破坏死锁发生的4个必要条件
互斥:此条件无法否定
占有并等待:每个进程执行前必须获得所有的资源;进程在没有资源时才可以申请资源。问题是资源利用率偏低,而且可能发生饿死现象。
非抢占:如果一个进程占有资源并申请访问另一个不能立即分配的资源,则已分配的资源可以被抢占。常用于CPU寄存器和内存。
循环等待:为每个资源类型分配一个唯一整数,每个进程只能按递增顺序申请资源。
上述方法会降低设备利用率和系统吞吐率。
3、死锁避免
安全状态
资源分配图算法
银行家算法