linux下我们可以调用fork函数创建子进程,创建的子进程将会得到父进程的数据空间、堆、栈......副本(采用写时复制机制),子进程将会继承父进程的信号掩码、信号处理方式、当前工作目录、会话id、组id......。当子进程退出时父进程应当及时获取子进程退出状态,否则,如果父进程是一直在运行,那么子进程的退出状态将一直保存在内存中,直到父进程退出才释放。

我们可以使用如下几种方法避免僵尸进程的产生:
1.在fork后调用wait/waitpid函数取得子进程退出状态。 2.调用fork两次(第一次调用产生一个子进程,第二次调用fork是在第一个子进
程中调用,同时将父进程退出(第一个子进程退出),此时的第二个子进程的父
进程id为init进程id(注意:新版本Ubuntu并不是init的进程id))。 3.在程序中显示忽略SIGCHLD信号(子进程退出时会产生一个SIGCHLD信号,我
们显示忽略此信号即可)。 4.捕获SIGCHLD信号并在捕获程序中调用wait/waitpid函数。
方法一:

#include "../common/common.h"

int main(void)
{
pid_t pid; if ((pid = fork()) < 0) {
perror("fork error");
return EXIT_FAILURE;
} else if (0 == pid) {
printf("[%ld] child process is running...\n", (long)getpid());
_exit(0);
} //sleep(15); if (waitpid(pid, NULL, 0) < 0) {
perror("waitpid error");
return EXIT_FAILURE;
} for (; ;) {
pause();
}
return EXIT_SUCCESS;
}
方法二:

#include <sys/wait.h>

#include "../common/common.h"

int main(void)
{
pid_t pid; if ((pid = fork()) < 0) {
perror("fork error");
return EXIT_FAILURE;
} else if (0 == pid) {
printf("first child is running..\n");
/**在第一个子进程中再次fork***/
if ((pid = fork()) < 0) {
perror("fork error");
return EXIT_FAILURE;
} else if (pid > 0) {/**父进程退出**/
printf("[%ld] first child is exit...\n", (long)getpid());
_exit(0);
} sleep(2);/**确保父进程先运行**/
printf("second process pid: %ld, second process's parent pid: %ld\n", (long)getpid(), (long)getppid());
//sleep(15);
printf("[%ld] is exit..\n", (long)getpid());
_exit(0);
} /***获得第一个子进程的退出状态***/
if (waitpid(pid, NULL, 0) < 0) {
perror("waitpid error");
return EXIT_FAILURE;
} for(;;)
pause(); return EXIT_SUCCESS;
}
方法三:

#include <signal.h>

#include "../common/common.h"

int main(void)
{
/***显示忽略SIGCHLD信号****/
if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) {
perror("signal error");
return EXIT_SUCCESS;
} pid_t pid;
int i;
/**产生10个子进程***/
for (i=0; i<10; ++i) {
if ((pid = fork()) < 0) {
perror("fork error");
return EXIT_FAILURE;
} else if (0 == pid) {
_exit(0);
} sleep(2);
continue;
} for (; ;)
pause(); return EXIT_SUCCESS;
}
方法四:

#include <signal.h>
#include <sys/wait.h> #include "../common/common.h" void sig_chld(int signo); int main(void)
{
/**捕获此信号, 此刻系统会立刻检测是否有次信号产生**/
if (signal(SIGCHLD, sig_chld) == SIG_ERR) {
handler_err("signal error to SIGCHLD");
} pid_t pid;
int i; for (i=0; i<10; i++) { if ((pid = fork()) < 0) {
handler_err("fork error");
} else if (0 == pid) {
printf("child pid: %d\n", getpid());
_exit(0);
} sleep(1);
continue;
} for (; ;) {
pause();
}
return EXIT_SUCCESS;
} /**捕获到信号后会立刻执行此段代码***/
void sig_chld(int signo)
{
printf("receive child signal\n"); if (waitpid(-1, NULL, 0) < 0) {
perror("waitpid error");
} if (signal(SIGCHLD, sig_chld) == SIG_ERR) {
perror("signal error to SIGCHLD");
} }

linux下避免僵尸进程的几种方法的更多相关文章

  1. 避免产生僵尸进程的N种方法(zombie process)

    http://blog.csdn.net/duyiwuer2009/article/details/7964795 认识僵尸进程 1.如果父进程先退出 子进程自动被 init 进程收养,不会产生僵尸进 ...

  2. Linux下查看线程数的几种方法汇总

    Linux下查看线程数的几种方法汇总 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Linux下查看某个进程的线程数量 pstree命令以树状图显示进程间的关系(display ...

  3. Linux下查看磁盘挂载的几种方法

    Linux下查看磁盘挂载的几种方法 第一种方法:df命令 # df -hT Filesystem Type Size Used Avail Use% Mounted on devtmpfs devtm ...

  4. Linux下查看磁盘挂载的三种方法

    Linux下查看磁盘挂载的三种方法 2009-06-05 23:17 好久没有更新日志了,呵呵.不是没有要写的东东.实在抽不出时间来写,要准备公司的考试呢,C++考试.已经有七个月没有写C++代码了, ...

  5. Linux下杀僵尸进程办法

    1) 检查当前僵尸进程信息 # ps -ef | grep defunct | grep -v grep | wc -l 175 # top | head -2 top - 15:05:54 up 9 ...

  6. linux下的僵尸进程处理SIGCHLD信号

    什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打开的文件等,但内核为每一个终止子进程保存了一定量的信息.这些信息至少包括进程ID,进程的终止状态,以及该 ...

  7. [转] linux下的僵尸进程处理SIGCHLD信号

    什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打开的文件等,但内核为每一个终止子进程保存了一定量的信息.这些 信息至少包括进程ID,进程的终止状态,以及 ...

  8. linux下的僵尸进程处理SIGCHLD信号【转】

    转自:http://www.cnblogs.com/wuchanming/p/4020463.html 什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打 ...

  9. Linux下分析bin文件的10种方法

    这世界有10种人,一种人懂二进制,另一种人不懂二进制. --鲁迅 大家好,我是良许. 二进制文件是我们几乎每天都需要打交道的文件类型,但很少人知道他们的工作原理.这里所讲的二进制文件,是指一些可执行文 ...

随机推荐

  1. Maven下把父项目下的子项目导出到myeclipse中

    第一种在父项目下已有子项目:右击空白------import 第二步Maven4MyEclipse-----------Existing  Maven  Projects 第三部选择父项目下面的子项目 ...

  2. windows下安装python包

    1.windows下成功安装好python后,在安装目录的Scripts目录下有easy_install和pip工具 2.如果没有安装pip,进入命令行,切换到python的安装目录下的Scripts ...

  3. 如何将拷贝过来的数据 *.ibd 文件生效

    1.将拷贝的数据文件   "qqq.idb"放在自己的数据库中. 一般存放在  mysql/ data/ databasename 下 2. "qqq.idb" ...

  4. jquery——幻灯片(只动一屏)

    制作天天生鲜的幻灯片部分 贴了全部代码: main.html: <!DOCTYPE html> <html lang="en"> <head> ...

  5. formatter 操作列表的合并

    {field:'22',title:'操作',width:250,align:'center',sortable:true,formatter : function(value, row, index ...

  6. c语言字符串操作总结(转)

    本文转自:http://www.jb51.net/article/37410.htm 1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 s ...

  7. Maven的学习资料收集--(四)使用Maven构建Web项目-测试

    2014-08-04 23:21 2人阅读 评论(0) 收藏 编辑 删除   目录(?)[+]   [-] 在srcmainjava下新建一个Servlet 修改webxml 新建JSP 测试   在 ...

  8. 《Head First 设计模式》之单件模式

    单件模式(Singleton) ——确保一个类只有一个实例,并提供全局访问点. 有一些对象其实我们只需要一个,比如线程池.缓存.对话框.处理偏好设置和注册表的对象.日志对象.如果制造出多个实例,就会导 ...

  9. Teradata 认证系列 - 1. TCPP这是个啥

    一看历史,好几年没发帖...正好最近在自学teradata认证(学也不一定学的完,最后也不一定去考,仅仅安慰一下不想碌碌无为的内心) 网上一搜,百度上的中文相关资料简直为0.这个不奇怪,毕竟都没什么人 ...

  10. React:关于在delegate中的confirm或者alert在多次弹出

    如何试验出是delegate的过程就不解说了 直接上解决方案:(当然我的解决方案只适合一定情况) 取比较简单的代码来解说,例如 我一开始使用delegate的原因是由于我有部分html页面是ajax中 ...