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. for in在对象和数组中的应用

    var obj = { name:'lei', be:'dd', age:23 } for(var poo in obj){ alert('对象的属性和值为:'+poo+':'+obj[poo]); ...

  2. 阿里云服务器 linux 怎么安装php(PHPSTUDY)开发环境

    1.首先登录行云管家(https://yun.cloudbility.com/login.html) wget -c http://lamp.phpstudy.NET/phpstudy.bin //下 ...

  3. Duff and Meat(贪心)

    Duff is addicted to meat! Malek wants to keep her happy for n days. In order to be happy in i-th day ...

  4. js 监听浏览器刷新还是关闭事件

    转载大神 http://www.cnblogs.com/gavin0517/p/5827405.html

  5. Python 列表list 和 字符串str 互转

    一.列表list转字符串str 命令(python2.x):''.join(list) 命令(python2.x):''.join(str(s) for s in list) 其中,引号中是字符之间的 ...

  6. 11-----broder(边框)

    边框 border:边框的意思,描述盒子的边框 边框有三个要素: 粗细 线性样式 颜色 如果颜色不写,默认是黑色.如果粗细不写,不显示边框.如果只写线性样式,默认的有上下左右 3px的宽度,实体样式, ...

  7. 07.Spring Bean 加载 - BeanDefinitionReader

    基本概念 BeanDefinitionReader ,该接口的作用就是加载 Bean. 在 Spring 中,Bean 一般来说都在配置文件中定义.而在配置的路径由在 web.xml 中定义.所以加载 ...

  8. Ubuntu apt-get update中断的时候会出现一个错误导致不能再apt-get update

    错误描述为:Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable) E: Un ...

  9. es6-Iterator与for...of

    Iterator(遍历器)的概念 JavaScript原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6又添加了Map和Set.这样就有了四种数据集合,用户还可以组合 ...

  10. Js/Jquery获取input file的文件名

    html代码:     <input type="file" name="file" id="file" class="in ...