1、进程生命周期
Linux操作系统属于多任务操作系统,系统中的每个进程能够分时复用CPU时间片,通过有效的进程调度策略实现多任务并行执行。而进程在被CPU调度运行,等待CPU资源分配以及等待外部事件时会属于不同的状态。下图描述了进程之间的状态关系:
- 运行状态:表示进程此刻正在运行。注,图示中的“运行”状态,并不对应TASK_RUNNING状态,TASK_RUNNING实际表示当前进程被填入CPU就绪队列,属于图示“等待”状态,后续在源码分析中会详细说明;
- 等待状态:表示进程外部事件已满足,并已被分配CPU资源,但由于当前CPU被其他进程占用,尚未被调度;
- 睡眠状态:表示进程需要等待外部事件满足方可被CPU调度。这里外部事件,比如在阻塞IO环境下,服务端进程等待客户端进程发送TCP三路握手连接请求;
- 终止状态:表示进程退出事件发生,进程所属用户地址空间与内核地址空间被释放。
- 对于进程终止的终止,这里有种特殊情况,父进程需要接收子进程退出时发出的SIGCHILD信号,完成对子进程task_struct进程结构体的释放任务,若父进程未能完成上述处理,则会导致名义上子进程已退出,但实际内核进程链表中仍然保留子进程信息,即僵尸进程。在Linux操作系统中,采用ps命令可以看到僵尸进程。(简述一下ps命令的原理:proc文件系统中以进程pid为名保存了系统中的进程信息,其通过遍历内核进程链表的方式获取进程信息,ps命令返回proc文件系统下的进程信息)
2、task_struct进程结构体
在Linux操作系统下,对进程的操作,都是通过task_struct数据结构来实现的。
结构体部分信息解释如下:
- volatile long state,描述了进程的不同状态,对应了进程生命周期。
- 若干struct list_head结构体,定义了进程内核链表指针,进程父进程,子进程等。
- struct mm_struct *mm 进程地址空间。关于这一块内容涉及到了Linux内存管理,会在分析Linux内存管理时详细介绍。
- Pid_t pid 进程ID。Linux操作系统中进程的唯一标识。注,进程页目录基地址也可以作为进程的唯一标识,用于访问进程地址空间。
- Char comm[TASK_COMM_LEN] 进程名称。
- Int prio, static_prio, normal_prio是与进程调度相关的优先级。具体的描述在分析到Linux进程调度的过程中再详细说明。