进程的状态:
(查看进程状态的命令:ps axj | ps aux)
R运行状态:表示一个进程随时随地可以被操作系统调度。
S睡眠状态:表示进程在等待事件的完成(比如while(1)sleep(1);会进入睡眠状态);
D磁盘休眠状态:有时候也叫不可中断睡眠状态,在这个状态的进程通常会等待IO的结束。
T停止状态:可以通过发送SIGSTOP信号给进程来停止进程,可以发送SIGCONT信号让进程继续运行。
写了一个无限循环程序
查看状态为S状态。
发了SIGSTOP信号之后,在查看进程状态为T状态。
再次发了SIGCONT信号之后,在查看进程状态为S状态。
X死亡状态:该状态是返回状态,在任务列表中看不到;
Z僵尸状态:子进程退出,父进程还在运行,但是父进程没有读到子进程的退出状态,子进程进入僵尸状态。
先来一段断码,子进程5秒之后退出,而父进程一直在运行。
观察到子进程5秒之后变成了Z状态,也就是僵尸进程。
问题1:为什么要有僵尸进程?
答:子进程退出后,父进程继续运行,但是父进程没有去读取子进程的退出状态信息,子进程被父进程fork出来是为了完成某些任务的,这时候如果子进程没有进入僵尸状态,退出了,那么父进程就无法得知退出的这个子进程把任务完成的怎么样了,所以子进程必须维持僵尸状态,来等待父进程的读取。
问题2:僵尸进程的危害。
答:子进程维持僵尸状态,等待父进程来读取,操作系统也杀不死子进程,但是如果父进程一直不读取子进程的退出状态,那么子进程也就一直处于Z状态,而维持这种状态本身也需要资源(数据保存在PCB中),所以就会造成内存资源的浪费,也就是资源泄露。
解决僵尸进程问题
1.父进程等待子进程(wait_pid)
示例代码:
结果:子进程没有僵尸进程,被父进程等待回收;
2.signal信号忽略子进程(SIGCHLD)
示例代码:
结果:
3.子进程fork出子进程的子进程,将子进程退出,让子进程的子进程成为孤儿进程,等待1号进程回收。
另一种进程:孤儿进程
概念:父进程如果提前退出,子进程还在运行,此时子进程就被称为孤儿进程,孤儿进程被1号进程init进程领养,当然会有init进程回收。
父进程在3秒后退出,子进程sleep20秒。
开始的时候,子进程和父进程同时运行,3秒后父进程退出,子进程的ppid变成了1,就是我们所说的1号进程init(也就是bash)。