详解linux下避免僵尸进程的几种方法
发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,linux下我们可以调用fork函数创建子进程,创建的子进程将会得到父进程的数据空间、堆、栈......副本(采用写时复制机制),子进程将会继承父进程的信号掩码、信号处理方式、当前工作目录、会话id、
千家信息网最后更新 2025年12月02日详解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#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#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#include #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"); }}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
进程
信号
个子
方法
状态
函数
程序
运行
僵尸
代码
信号处理
内存
内容
再次
副本
同时
就是
数据
方式
是在
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
qq联系赵女士 网络安全
阿里云的数据库在哪里
网络安全科普教育手抄报的字
智能掌上办公请配置服务器地址
数据库维护与控制ddl作用
科技前沿互联网
数据库补码
数据库考啥
软件开发开待遇
微企网络技术有限公司
数据库加磁盘阵列
北京恒山系列鲲鹏服务器
数据库作业第三章习题答案
小学生防沉迷网络安全教育手抄报
上海通信网络技术结构设计
数据库普通形式
基于git的软件开发
永嘉县互联网科技有限公司
惠州市网络安全教育平台
网络安全4所高新受表彰
班玛网络技术有限公司
网络安全事业发展历程
租一个服务器
服务器磁盘安装有顺序吗
数据库文档编辑器
数据库数据字典
广州办公系统软件开发哪家便宜
数据库表作为一个对象
局域网搭建cdn服务器
内网网络安全现状自查