文章目录
- 进程基础
- pcb
- 状态
- 优先级
- 进程的调度
- 常见的调度算法
- 进程的通信方式
进程基础
pcb
操作系统在创建进程时,会给进程分配一块PCB(process control block 进程控制块),对应linux上就是task_struct
结构体,PCB里面存储着进程所需的所有信息资源,所以PCB就是进程/线程的标志,他们之间是一一对应的关系。
task_struct
- 标示符:与进程相关的唯一标识符,用来区别正在执行的进程和其他进程。对应PID
- 状态:描述进程的状态,因为进程有挂起,阻塞,运行等好几个状态,所以都有个标识符来记录进程的执行状态。
- 优先级:如果有好几个进程正在执行,就涉及到进程被执行的先后顺序的问题,这和进程优先级这个标识符有关。
- 上下文数据:进程执行时处理器的寄存器中的数据。
- 程序计数器:程序中即将被执行的下一条指令的地址。
- 内存指针:程序代码和进程相关数据的指针。
- I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表等。
- 记账信息:包括处理器的时间总和,记账号等等。
状态
一个进程会有很多状态,内核源码如下
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
R:运行状态。
S:睡眠状态。
T:停止状态。可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
Z:僵尸状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。僵尸进程会造成资源浪费,内存泄漏。
- 补充一个知识点:
孤儿进程:指父进程在子进程退出前退出,子进程就变成了孤儿进程。此时子进程就会被1号init进程领养,后续的资源回收也由init进程管理。
优先级
用命令ps -l
查看
UID:执行者的身份
PPID:pid的父进程id
PID:进程的唯一标识符
PRI:表示进程的优先级,PRI越小,优先级越高
进程的调度
进程的调度,就是因为状态的变化而引起的。在linux系统中,进程和线程没有明确的区分,都称为轻量级进程,但是这里先不讨论linux系统下的情况,说说普遍的情况。
- 进程是资源分配的基本单位,线程是独立调度的基本单位。
要想调度进程,首先操作系统会为其开辟一段内存空间,即PCB,里面存放了进程所运行时的所有资源,然后根据调度算法来上CPU执行。
具体调度过程可以参考此文:一文看懂进程和线程调度,这里不展开叙述。
常见的调度算法
- 非抢占式进程调度算法
① 先到先服务 FCFS:按照进程到达的先后顺序进行调度,先到的进程就先被调度,也就是说,等待时间越久的越优先得到服务。
② 最短作业优先 SJF:每次调度时选择当前已到达的、且运行时间最短的进程。
③ 高响应比优先 HRRN:只有当前运行的进程主动放弃 CPU 时(正常/异常完成,或主动阻塞),才需要进行调度,调度时计算所有就绪进程的响应比,为响应比最高的进程分配 CPU。
响应比 = (进程的等待时间 + 进程需要的运行时间) / 进程需要的运行时间
- 抢占式进程调度算法
① 最短剩余时间优先 SRTN:最短作业优先的抢占式版本。
当一个新的进程到达时,把它所需要的整个运行时间与当前进程的剩余运行时间作比较。如果新的进程需要的时间更少,则挂起当前进程,运行新的进程,否则新的进程等待。
② 轮转调度算法 RR:又称时间片调度算法。
调度程序每次把 CPU 分配给就绪队列首进程使用规定的时间间隔,称为时间片,通常为 10ms ~ 200ms,就绪队列中的每个进程轮流地运行一个时间片,当时间片耗尽时就强迫当前运行进程让出 CPU 资源,转而排到就绪队列尾部,等待下一轮调度。所以,一个进程一般都需要多次轮转才能完成。
- 最高优先级调度算法 HPF
最高优先级调度算法就是从就绪队列中选择最高优先级的进程进行运行
① 静态优先级:创建进程时候,就预先规定优先级,并且整个运行过程中该进程的优先级都不会发生变化。一般来说,内核进程的优先级都是高于用户进程的。
② 动态优先级:根据进程的动态变化调整优先级。比如随着进程的运行时间增加,适当的降低其优先级;随着就绪队列中进程的等待时间增加,适当的升高其优先级。
进程的通信方式
进程间的通信方式有很多,常见的有7种:
- 命名管道,管道:linux之《管道》
- 共享内存:linux之《共享内存》
- 消息队列
- 信号量
- 套接字
- 信号