进程的状态:

(查看进程状态的命令:ps axj | ps aux)

R运行状态:表示一个进程随时随地可以被操作系统调度。

S睡眠状态:表示进程在等待事件的完成(比如while(1)sleep(1);会进入睡眠状态);

D磁盘休眠状态:有时候也叫不可中断睡眠状态,在这个状态的进程通常会等待IO的结束。

T停止状态:可以通过发送SIGSTOP信号给进程来停止进程,可以发送SIGCONT信号让进程继续运行。

java linux 启动后休眠_僵尸进程


写了一个无限循环程序

java linux 启动后休眠_进程等待_02


查看状态为S状态。

java linux 启动后休眠_进程等待_03


发了SIGSTOP信号之后,在查看进程状态为T状态。

java linux 启动后休眠_进程状态_04


再次发了SIGCONT信号之后,在查看进程状态为S状态。

X死亡状态:该状态是返回状态,在任务列表中看不到;

Z僵尸状态:子进程退出,父进程还在运行,但是父进程没有读到子进程的退出状态,子进程进入僵尸状态。

java linux 启动后休眠_僵尸进程_05


先来一段断码,子进程5秒之后退出,而父进程一直在运行。

java linux 启动后休眠_java linux 启动后休眠_06


观察到子进程5秒之后变成了Z状态,也就是僵尸进程。

问题1:为什么要有僵尸进程?

答:子进程退出后,父进程继续运行,但是父进程没有去读取子进程的退出状态信息,子进程被父进程fork出来是为了完成某些任务的,这时候如果子进程没有进入僵尸状态,退出了,那么父进程就无法得知退出的这个子进程把任务完成的怎么样了,所以子进程必须维持僵尸状态,来等待父进程的读取。

问题2:僵尸进程的危害。

答:子进程维持僵尸状态,等待父进程来读取,操作系统也杀不死子进程,但是如果父进程一直不读取子进程的退出状态,那么子进程也就一直处于Z状态,而维持这种状态本身也需要资源(数据保存在PCB中),所以就会造成内存资源的浪费,也就是资源泄露。

解决僵尸进程问题

1.父进程等待子进程(wait_pid)

示例代码:

java linux 启动后休眠_僵尸进程_07


结果:子进程没有僵尸进程,被父进程等待回收;

java linux 启动后休眠_进程状态_08


2.signal信号忽略子进程(SIGCHLD)

示例代码:

java linux 启动后休眠_java linux 启动后休眠_09


结果:

java linux 启动后休眠_孤儿进程_10


3.子进程fork出子进程的子进程,将子进程退出,让子进程的子进程成为孤儿进程,等待1号进程回收。

另一种进程:孤儿进程

概念:父进程如果提前退出,子进程还在运行,此时子进程就被称为孤儿进程,孤儿进程被1号进程init进程领养,当然会有init进程回收。

java linux 启动后休眠_进程状态_11


父进程在3秒后退出,子进程sleep20秒。

java linux 启动后休眠_进程状态_12


开始的时候,子进程和父进程同时运行,3秒后父进程退出,子进程的ppid变成了1,就是我们所说的1号进程init(也就是bash)。