linux下避免僵尸进程的几种方法
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下避免僵尸进程的几种方法的更多相关文章
- 避免产生僵尸进程的N种方法(zombie process)
http://blog.csdn.net/duyiwuer2009/article/details/7964795 认识僵尸进程 1.如果父进程先退出 子进程自动被 init 进程收养,不会产生僵尸进 ...
- Linux下查看线程数的几种方法汇总
Linux下查看线程数的几种方法汇总 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Linux下查看某个进程的线程数量 pstree命令以树状图显示进程间的关系(display ...
- Linux下查看磁盘挂载的几种方法
Linux下查看磁盘挂载的几种方法 第一种方法:df命令 # df -hT Filesystem Type Size Used Avail Use% Mounted on devtmpfs devtm ...
- Linux下查看磁盘挂载的三种方法
Linux下查看磁盘挂载的三种方法 2009-06-05 23:17 好久没有更新日志了,呵呵.不是没有要写的东东.实在抽不出时间来写,要准备公司的考试呢,C++考试.已经有七个月没有写C++代码了, ...
- Linux下杀僵尸进程办法
1) 检查当前僵尸进程信息 # ps -ef | grep defunct | grep -v grep | wc -l 175 # top | head -2 top - 15:05:54 up 9 ...
- linux下的僵尸进程处理SIGCHLD信号
什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打开的文件等,但内核为每一个终止子进程保存了一定量的信息.这些信息至少包括进程ID,进程的终止状态,以及该 ...
- [转] linux下的僵尸进程处理SIGCHLD信号
什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打开的文件等,但内核为每一个终止子进程保存了一定量的信息.这些 信息至少包括进程ID,进程的终止状态,以及 ...
- linux下的僵尸进程处理SIGCHLD信号【转】
转自:http://www.cnblogs.com/wuchanming/p/4020463.html 什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打 ...
- Linux下分析bin文件的10种方法
这世界有10种人,一种人懂二进制,另一种人不懂二进制. --鲁迅 大家好,我是良许. 二进制文件是我们几乎每天都需要打交道的文件类型,但很少人知道他们的工作原理.这里所讲的二进制文件,是指一些可执行文 ...
随机推荐
- PIL图片格式转换
PIL格式转换 原图: #!/usr/local/bin/python # -*- coding: utf8 -*- from PIL import Image, ImageFilter import ...
- Linux之dstat命令
dstat命令是一个用来替换vmstat.iostat.netstat.nfsstat和ifstat这些命令的工具,是一个全能系统信息统计工具.与sysstat相比,dstat拥有一个彩色的界面,在手 ...
- springBoot实现socketio
https://github.com/mrniko/netty-socketio-demo https://github.com/mrniko/netty-socketio
- python中深复制和浅复制区别
在python中,对象赋值实际上是对象的的引用,当创建一个对象,然后把它赋值给另外一个变量的时候,python没有拷贝这个对象,而只是拷贝了这个对象的引用,多以就出现了浅复制,即复制后原对象改变后,复 ...
- java——集合、泛型、ArrayList、LinkedList、foreach循环、模拟ktv点歌系统
集合:一系列特殊的类,这些类可以存储任意类型的对象,长度可变,集合类都在java.util包中. 但是集合记不住对象的类型,当把对象从集合中取出时这个对象的编译类型就变成了Object类型.这样在取元 ...
- (转)linux磁盘分区fdisk分区和parted分区
linux磁盘分区fdisk分区和parted分区 原文:http://www.cnblogs.com/jiu0821/p/5503660.html ~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- 新浪php面试题
1. echo count("abc"); 输出什么?答:"1" count — 计算数组中的单元数目或对象中的属性个数int count ( mixed $v ...
- xmanger图形化登陆远程服务器
由于网上的资料比较杂,经过本人整理实际操作验证,保证ok 本人的服务器系统为centos5.8 下面的都是centos服务器上的操作,需要简单的配置下: win客户端使用xmanger软件:首先是服 ...
- 如何在数据库中导入excel文件内的数据
如何在数据库中轻松导入excel格式的文件 1)打开sql server,找到要导入数据的数据库,右键>>任务>>导入数据 2)按照图示选择要导入的excel 3)选择导入到哪 ...
- 树莓派-(一)开箱到点亮一些坑(无屏、无wlan、无直连键鼠)
0x00.前期准备: 材料: 树莓派3b+ 板子 * 1,适配电源 * 1,网线 * 2,sd卡16G * 1,读卡器 * 1 安装时注意,3b+三个散热片贴好.小风扇接线要接对 工具: 0x01. ...