进程的状态,本质上就是一个整型变量,在task_struct中的一个整型变量。
状态的存在决定了你的后续行为动作。
Linux中可能会存在多个进程都要根据它的状态执行后续的动作,并且进程可能会存在多个相同的状态,所以进程排队。
一个CPU一个进程队列。
当我们的进程在等待软硬件资源的时候,如果资源还没有就绪,我们的进程task_struct只能将自己设置为阻塞状态,并且将自己的pcb链入等待的资源提供的等待队列。
进程状态的变化,对应的(引起的)是pcb会被操作系统OS变迁到不同的队列中进行排队。
运行状态 R
阻塞状态
当一个进程在cpu的运行队列中,先时运行状态,但是这个进程需要的硬件资源还没有准备好,例如从键盘中读取数据,此时还没有读取到,此时操作系统会将这个进程从cpu的运行队列中拿下来,链入到键盘硬件相对应的排队队列中,并将这个进程的状态设置为阻塞状态,当进程从键盘中获取足够的资源的时候,操作系统再将这个进程拿到CPU的运行队列中重新进行排队。
挂起状态
阻塞挂起
当计算机的资源比较吃紧的时候,某个进程不运行,将其先写入磁盘从队列中取下,当资源充足时或者运行这个进程的时候再从磁盘中读取出来写入到内存,进行执行。
操作系统在被逼急了的情况下,是会杀掉进程的。
Linux内核下的进程状态
static const char *task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"T (tracing stop)", /* 8 */
"Z (zombie)", /* 16 */
"X (dead)" /* 32 */
};
前后台进程
前后台进程,前台进程可以直接杀掉,后台进程只能使用kill杀掉,状态带+就是前台进程,不带就是后台进程。
kill -19 pid
kill -18 pid
为什么存在Z状态。
创建一个进程是希望这个进程给用户完成工作的,子进程必须得有结果数据,Pcb中的。
什么时Z状态。
进程已经退出了,但是当前的状态需要自己维持住,供上层读取,必须处于Z状态。
如果父进程不读取呢。
如果父进程不读取这个僵尸进程,僵尸状态的进程会一直存在。task_struct对象也要一直存在,需要占用着内存。此时会出现内存泄漏的问题。
所有的进程在退出的时候,都要先经过Z状态。
defunct : 无效的,死亡的。
当父进程比子进程提前结束,父进程会被他的父进程bash回收,此时父进程被回收后,子进程就变成了孤儿,此时子进程会被1号进程领养,1号进程就是系统进程。此时子进程不仅变成了孤儿进程也变成了后台进程。