进程状态在PCB里面也就是一个整型变量,int status。
状态变化本质上是:
(1)修改pcb中status的值
(2)将pcb链入不同的队列中
一、操作系统教材中的状态:
1.运行状态
每一个CPU都会在系统层面维护一个运行队列
2.阻塞状态
如果使用cin,scanf等函数,需要从键盘读取数据,但我们不输入,键盘上的数据就没有就绪,即访问的资源没有就绪,就会阻塞。
操作系统也会对底层硬件进行先描述,再组织。构建dev结构体,包含硬件的各种属性,阻塞队列等。并用链表将多个硬件dev结构体组织起来。
进程访问的硬件资源没有就绪时,会把它的pcb从运行队列踢出,加入到硬件的阻塞队列,此时进程变为阻塞状态。OS一定最先知道硬件设备的状态变化的,如果阻塞后硬件资源就绪了,OS就会把进程从dev的阻塞队列踢出,并加入到运行队列,再把状态改为运行状态(称为将该进程唤醒)
3.挂起状态
有阻塞挂起和就绪挂起,一般是阻塞挂起。如果进行就绪挂起,将该进程的数据(数据结构对象)交换到swap分区,由于该进程随时会被CPU调度,势必会导致大量的换入换出,影响效率。内存严重不足时会进行挂起,甚至杀掉进程
swap分区是磁盘上的一块区域,一般不会设置过大,如果设置太大了,OS会过度依赖swap分区,频繁进行换入换出,降低效率。将swap分区设置一个合理的大小,使OS能不交换尽量不交换。分区大小一般与内存保持一致
二、Linux中的进程状态
S+对应特殊的阻塞状态,S+后面带个+表示这是个前台进程。
如果使用:
./mytest & //在后台运行
此时在后台运行,就不会有+
S:休眠状态,浅度睡眠,可以被终止,会对外部的信号做出响应(如能被信号干掉)。
D:休眠状态,深度睡眠。专门针对磁盘来设计的。
当进程向磁盘写入关键数据时,进入深度睡眠。如果用户看到D状态,说明磁盘基本上无法响应了,导致OS也会挂掉。遇到D状态,重启可能也关不了机。
T:暂停状态。在进程访问软件资源的时候,可能暂时不让进程访问,就将进程设置为STOP
t:debug程序时,追踪程序,遇到断点,进程暂停了
两者也算阻塞状态
使用gdb进行调试也是一个进程,调试时gdb不断向mytest发送CONTINUE信号和STOP信号
X:终止状态
Z:僵尸状态
我们创建一个进程是为了让它帮我们完成任务,进程退出后,我们(父进程)需要知道进程把任务完成地怎么样。要让父进程或OS读取退出进程的退出信息,得知退出原因。
所以进程退出时,OS会把退出信息写入到当前进程的PCB中,将代码和数据释放,并维护PCB直到被父进程读取。
此时进程退出了,但PCB还没有被父进程或OS读取,OS必须维护这个退出进程的PCB结构,这个状态称为僵尸状态。只有被读取后,PCB被改为X状态,才会被释放。
OS或父进程不读取,PCB会一直存在。如果不及时处理,会造成内存泄漏。
孤儿进程:
如果父进程比子进程先退出,子进程会被1号进程领养,变成孤儿进程,1号进程就是操作系统(systemd | initd)。