前言
僵尸进程和孤儿进程是Linux中极为重要的两个种进程状态, 本文将会围绕这三个问题: 是什么? 为什么? 如何产生的? 详细的介绍这两种进程; 以及一些使用场景.
僵尸进程
在了解孤儿进程之前, 需要先引入僵尸进程的概念;
什么是僵尸进程?
僵尸进程: 就是处于僵死状态的进程;
僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程, 没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
为什么会产生僵尸进程?
进程 = 进程PCB + 进程的代码和数据; 进程存在就一定会占用一定的空间;
为什么创建进程? 很简单, 为了让它帮我们完成某些任务;
进程执行完毕之后, 核心任务: 将进程PCB 以及进程的代码和数据释放掉;
父进程创建子进程, 让子进程去完成某些任务, 那么父进程可能有需求: 需要知道子进程的任务完成情况;
子进程退出时, 会由OS将子进程的退出信息写入到进程PCB中, 允许进程的代码和数据被释放, 但是进程PCB不会立即释放, 要让父进程知道 子进程退出的信息, 得知子进程退出的原因(正常退出或者异常退出);
当一个进程退出了, 代码和数据已经被释放, 只要PCB中的退出信息还没有被 OS或父进程读取到, OS就必须维护这-退出进程的PCB, 此时的进程状态就是Z状态, 也就是僵尸状态;
只有被父进程读取后(wait)后, PCB的状态才会将Z状态改为X状态, 然后被OS回收;
危害 :
一个进程处于Z状态, 父进程一直不读取回收, 那么该进程的PCB就会一直存在, 造成内核级的内存泄露(内核资源浪费);
这种危害主要在一些服务器中较为明显, 服务器的服务会长时间的运行, 长时间的积累就会导致服务的效率变慢, 虽然重启服务器可以将僵尸进程的PCB资源释放, 但是对于服务器而言, 不可能轻易的关闭后重启;
模拟僵尸进程的产生:
int main()
{
pid_t id = fork();
if (id < 0) return 1;
else if (id == 0) //子进程执行5秒后退出
{
int cnt = 5;
while (cnt)
{
printf("I am child , runing time:%d\n", cnt--);
sleep(1);
}
printf("I am child ,dead!:%d\n", cnt--);
exit(2);
}
else // 父进程一直运行, 但不回收子进程
{
while (1)
{
printf("I am father, running times!\n");
sleep(1);
}
}
return 0;
}
使用指令监控进程的状态变化:
while :; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep; sleep 1; done // myprocess为需要监控的进程名
孤儿进程
什么是孤儿进程?
父进程先退出,子进程就称之为“孤儿进程”
父进程先退出,? 那么子进程退出时不就没有进程来读取子进程的PCB退出信息了吗?
为什么被1号进程领养?
为了避免子进程退出, 没有进程读取子进程PCB的情况发生;
父进程一旦退出, 子进程如果还没有执行完毕, 就会被OS领养, 当子进程执行完毕退出后, 由OS进行读取回收;
模拟孤儿进程的产生:
int main()
{
pid_t id = fork();
if (id < 0) return 1;
else if (id == 0) // 子进程一直运行
{
while (1)
{
printf("I am child ...\n");
sleep(1);
}
}
else // 父进程运行5秒后退出
{
int cnt = 5;
while (cnt)
{
printf("I am father, running time:%d\n", cnt--);
sleep(1);
}
printf("I am father dead:%d\n", cnt--);
exit(2);
}
return 0;
}
监控指令:
while :; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep; sleep 1; done // myprocess为需要监控的进程名
孤儿进程在实际应用中的使用:
孤儿进程的特性在一些并发服务中可以使用, 服务器服务接收请求, 对请求进行处理时可以让任务处理的主进程创建子进程去执行, 而主进程立即退出, 此时子进程就会变成孤儿进程, 被OS领养, 当子进程执行完毕后, 由OS进行回收, 任务处理的进程也不需要一直的等待子进程处理完毕;
总结
孤儿进程是为了避免父进程退出, 造成子进程无法被读取, 导致子进程变成僵尸进程的情况; 僵尸进程对于服务器服务来说危害极大, 在编写服务时要特别注意; 好了以上便是本文的全部内容, 希望对你有所帮助, 感谢阅读!