linux 僵尸(defunct)进程和孤儿进程
2015-02-04 20:11
691 查看
在fork或者exec函数创建一个新的进程,为了收集新进程的退出状态并防止出现僵尸进程(zombie process),父进程应该调用waitpid或者wait等待子进程退出。
在unix/linux 系统中,一个子进程结束了,但是它的父进程没有等待(调用wait / waitpid)它(前提是它的父进程没有退出,这里面操作系统认为它有父进程,操作系统不会清除该进程), 那么它将变成一个僵尸进程,如果父进程也接着退出的话,操作系统会统一将其清除。
之所以被称为僵尸进程,因为它虽然死掉了,但是在进程表中依然存在。子进程退出后分的内存和其他资源都被释放,但它还是在内核进程表中保留一条,内核在父进程回收子进程的退出状态前一直保留它。有一两个僵尸进程不算什么,但是一旦程序频繁的执行fork 或者exec却又不能收集退出状态,那么最终、将会填满进程表这会影响性能,可能导致系统重启。
通过ps命令这里使用ps -u hsc (这里hsc是用户名),我们可以看到zombie_test进程有<defunct>defunct的意思就是已死的,无效的,不存在的。
如果子进程的父进程已经先结束了,此时而它的一个或多个子进程还在运行,这些子进程将成为孤儿进程,它们将由init进程收养。因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程, 看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init 来接管他,成为它的父进程……孤儿进程是正常的,不会给系统带来问题。
可以看到父进程退出后子进程的父进程的pid为1(init 进程)。
在unix/linux 系统中,一个子进程结束了,但是它的父进程没有等待(调用wait / waitpid)它(前提是它的父进程没有退出,这里面操作系统认为它有父进程,操作系统不会清除该进程), 那么它将变成一个僵尸进程,如果父进程也接着退出的话,操作系统会统一将其清除。
之所以被称为僵尸进程,因为它虽然死掉了,但是在进程表中依然存在。子进程退出后分的内存和其他资源都被释放,但它还是在内核进程表中保留一条,内核在父进程回收子进程的退出状态前一直保留它。有一两个僵尸进程不算什么,但是一旦程序频繁的执行fork 或者exec却又不能收集退出状态,那么最终、将会填满进程表这会影响性能,可能导致系统重启。
#include <stdio.h> #include <stdlib.h> #include<unistd.h> #include<sys/types.h> #include <string.h> #include <errno.h> int main(void) { pid_t pid = fork(); if (pid == -1) { printf("%s \n", strerror(errno)); return -1; } if (pid == 0) { printf("child exit!"); exit(0); //子进程直接退出 } else { printf("parent sleep 100s\n"); //父进程没有调用waitpid去等待子进程退出 sleep(100); } return 0; }
通过ps命令这里使用ps -u hsc (这里hsc是用户名),我们可以看到zombie_test进程有<defunct>defunct的意思就是已死的,无效的,不存在的。
如果子进程的父进程已经先结束了,此时而它的一个或多个子进程还在运行,这些子进程将成为孤儿进程,它们将由init进程收养。因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程, 看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init 来接管他,成为它的父进程……孤儿进程是正常的,不会给系统带来问题。
/* * main.c * * Created on: 2015-1-29 * Author: hsc */ #include <stdio.h> #include <stdlib.h> #include<unistd.h> #include<sys/types.h> #include <sys/wait.h> #include <string.h> #include <errno.h> int main(void) { pid_t pid = fork(); if (pid == -1) { printf("%s \n", strerror(errno)); return -1; } if (pid == 0) { while(1) { sleep(1); printf("child ppid=%d \n",getppid()); //打印出其父进程pid } } else { printf("parent exit\n"); //父进程直接退出 exit(0); } return 0; }
可以看到父进程退出后子进程的父进程的pid为1(init 进程)。
相关文章推荐
- 如何kill杀掉linux系统中的僵尸defunct进程
- .linux进程知识 程序存储、crontab、fork与vfork、exec、_exit()、wait()与waitpid()、孤儿和僵尸 文件读写 文件锁、select、poll
- Linux中的 僵尸进程 和 孤儿进程
- linux的僵尸进程和孤儿进程及解决方法
- 如何kill杀掉linux系统中的僵尸defunct进程
- Linux进程:僵尸与孤儿
- Unix/Linux操作系统:孤儿进程与僵尸进程[总结]
- linux系统编程之进程(三):进程复制fork,孤儿进程,僵尸进程
- linux进程知识 程序存储、crontab、fork与vfork、exec、_exit()、wait()与waitpid()、孤儿和僵尸
- Linux进程理解与实践(二)僵尸&孤儿进程 和文件共享
- (转载)Linux 僵尸进程与孤儿进程
- Linux 下 popen 函数引起的僵尸进程 defunct 以及解决办法
- linux系统编程之进程(三):进程复制fork,孤儿进程,僵尸进程
- 2.Linux复习 ---- 孤儿进程,僵尸进程
- Linux杀死fork产生的子进程的僵尸进程defunct
- Linux产生僵尸进程和孤儿进程及区别
- Linux 僵尸进程 孤儿进程
- Linux之僵尸进程和孤儿进程【总结】
- Linux进程理解与实践(二)僵尸&孤儿进程 和文件共享
- linux 孤儿进程和僵尸进程