操作系统之进程
1.进程与线程
- 进程是资源分配的基本单位
- 线程是独立调度的资本单位
进程与线程的区别
-
拥有资源
进程是资源分配的资本单位,但是线程不拥有资源,线程可以访问隶属进程的资源。
-
调度
线程是独立调度的基本单位,在同一进程中,线程的切换不会引起进程切换,从一个进程的线程切换到另一个进程中的线程会引起进程的切换
-
系统开销
进程的创建销毁涉及到分配回收资源,I/O操作,所以开销大
线程切换仅涉及到少量的寄存器内容,开销小
-
通信方面
线程直接通过读写同一进程中的数据进行通信 进程要通过IPC
2.进程状态的切换
- 就绪状态(ready):等待被调度
- 运行状态(running)
- 阻塞状态(waiting):等待资源
注意
- 只有就绪态和运行态可以相互准换,其他的都是单向准换。就绪状态的进程通过调度算法从而换的CPU时间,转为运行状态;运行状态的进程,在分配给他的时间片用完之后就会转为就绪状态,等待下一次调度。
- 阻塞状态是缺少需要的资源从而由运行状态转换而来,但是该资源不包括CPU时间,缺少CPU时间会从运行状态转换为就绪态。
3.进程调度算法
批处理系统
批处理系统没有太多的用户操作,在该系统中,调度算法目标是保证吞吐量和周转时间
-
先来先服务(FCFS)
非抢占式的调度算法,按照强求的顺序进行调度
有利于长作业,但不利于短作业,因为短作业必须一直等待前面的长作业执行完毕才能执行,而长作业有需要执行很长时间,造成了短作业等待时间过长。
-
短作业优先(SJF)
非抢占式的调度算法,按估计运行时间最短的顺序进行调度
长作业可能会饿死,处于一直等待短作业执行完毕的状态。因为如果一直有短作业到来,那么长作业永远得不到调度。
-
最短剩余时间优先(SRTN)
最短时间优先的抢占式版本,按剩余时间1的顺序进行调度。当一个新作业到达时,其整个运行时间与当前进程的剩余时间作比较。如果新进程需要的时间更短,运行新进程,否则新的进程等待。
交互式系统
交互式系统有大量的用户交互操作,在该系统中调度算法是快速得进行响应
-
时间片轮转
将所有就绪进程按FCFS的原则排成一个队列,每次调度时,把CPU时间分配给队首进程,该进程可以执行一个时间片。当时间片用完时,由计数器发出时钟中断,调度程序便停止该进程的执行,并将它送往队列的末端,同时继续把CPU时间分配给队首的进程。
-
优先级调度
每个进程分配一个优先级,按优先级进行调度
为了防止低优先级的进程永远得不到调度,可以随着时间的推移增加等待进程的优先级
实时系统
实时系统要求一个请求在一个确定的时间内得到相应
4.进程同步
-
临界区
对临界资源进行访问的那段代码称为临界区
为了互斥访问临界资源,每个进程在进入临界区之前。需要先进行检查
//entry section //critical section //exit section
-
互斥与同步
同步:多个进程按一定顺序执行
互斥:多个进程在同一时刻只有一个进程可以进入临界区
-
信号量
信号量是一个整型变量,可以对其执行down和up操作,也就是常见得P和V操作
- down:如果信号量大于0,执行-1操作;如果信号量等于0.进程睡眠,等待信号量大于0
- up:对信号量执行+1操作,唤醒睡眠1的进程让其完成down操作
-
管程
管程特性:在同一时刻只能有一个进程使用管程。进程在无法继续执行的时候不能一直占用管程,否则其他进程永远不能使用管程
5.经典同步问题
-
读者-写者问题
允许多个进程同时对数据进行读操作,但是不允许读和写以及写和写操作同时发生。
-
哲学家就餐问题
防止死锁:
- 必须同时拿起左右两根筷子
- 只有在相邻的两个邻居都没有进餐的情况下才允许进餐
6.进程通信
-
管道
限制
- 只支持半双工通信
- 只能在父子进程中使用
-
命名管道
去除了管道只能在父子进程中使用的限制
常用于客户-服务器应用程序中
-
消息队列
-
信号量
计数器,用于为多个进程提供对共享数据对象的访问
-
套接字
不同机器间的进程通信
-
共享存储
7.死锁
必要条件
- 互斥:每个资源要么已经分配给了一个进程,要么就是等待分配的
- 占有和等待:已经得到了某个资源的进程可以再请求新的资源
- 不可抢占:已经分配给一个进程的资源不能强制性地被抢占,他只能被占有他的进程显式释放
- 循环等待:有多个进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源
解决方法
-
鸵鸟策略
假装没有问题,顺其自然,不解决
-
死锁检测和死锁恢复
不试图阻止死锁,而是检测到死锁发生时,采取措施进行恢复
-
死锁预防
指破坏具体的四大条件
-
死锁避免
使用算法在程序运行时避免发生死锁。