嵌入式 Linux 的僵尸进程是什么?
目录
1、什么是僵尸进程?
2、僵尸进程的目的
3、怎么避免僵尸进程?
4、僵尸进程的处理方法
4.1 wait()连接
4.2 waitpid()函数
1、什么是僵尸进程?
首先内核会释放终止进程(调用了 exit 系统调用)所使用的所有存储区,关闭所有打开的文件 等,但内核为每一个终止子进程保存了一定量的信息。这些信息至少包括进程 ID,进程的终止状 态,以及该进程使用的 CPU 时间,所以当终止子进程的父进程调用 wait 或 waitpid 时就可以得 到这些信息。
而僵尸进程就是指:一个进程执行了 exit 系统调用退出,而其父进程并没有为它收尸(调用 wait 或 waitpid 来获得它的结束状态)的进程。 任何一个子进程(init 除外)在 exit 后并非马上就消失,而是留下一个称外僵尸进程的数据结构, 等待父进程处理。这是每个子进程都必需经历的阶段。另外子进程退出的时候会向其父进程发送一 个 SIGCHLD 信号。
2、僵尸进程的目的
设置僵死状态的目的是维护子进程的信息,以便父进程在以后某个时候获取。这些信息至少包 括进程 ID,进程的终止状态,以及该进程使用的 CPU 时间,所以当终止子进程的父进程调用 wait 或 waitpid 时就可以得到这些信息。如果一个进程终止,而该进程有子进程处于僵尸状态,那么 它的所有僵尸子进程的父进程 ID 将被重置为 1(init 进程)。继承这些子进程的 init 进程将清 理它们(也就是说 init 进程将 wait 它们,从而去除它们的僵尸状态)。
3、怎么避免僵尸进程?
1.通过 signal(SIGCHLD, SIG_IGN)通知内核对子进程的结束不关心,由内核回收。如果不 想让父进程挂起,可以在父进程中加入一条语句:signal(SIGCHLD,SIG_IGN);表示父进程忽略 SIGCHLD 信号,该信号是子进程退出的时候向父进程发送的。
2.父进程调用 wait/waitpid 等函数等待子进程结束,如果尚无子进程退出 wait 会导致父进 程阻塞。waitpid 可以通过传递 WNOHANG 使父进程不阻塞立即返回。
3.如果父进程很忙可以用 signal 注册信号处理函数,在信号处理函数调用 wait/waitpid 等待子进程退出。
4.通过两次调用 fork。父进程首先调用 fork 创建一个子进程然后 waitpid 等待子进程退出, 子进程再 fork 一个孙进程后退出。这样子进程退出后会被父进程等待回收,而对于孙子进程其父 进程已经退出所以孙进程成为一个孤儿进程,孤儿进程由 init 进程接管,孙进程结束后,init 会等待回收。
第一种方法忽略 SIGCHLD 信号,这常用于并发服务器的性能的一个技巧因为并发服务器常常 fork 很多子进程,子进程终结之后需要服务器进程去 wait 清理资源。如果将此信号的处理方式 设为忽略,可让内核把僵尸子进程转交给 init 进程去处理,省去了大量僵尸进程占用系统资源。
4、僵尸进程的处理方法
4.1 wait()连接
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
进程一旦调用了 wait,就立即阻塞自己,由 wait 自动分析是否当前进程的某个子进程已经退出,如果让它找 到了这样一个已经变成僵尸的子进程,wait 就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找 到这样一个子进程,wait 就会一直阻塞在这里,直到有一个出现为止。 参数 status 用来保存被收集进程退出时的一些状态,它是一个指向 int 类型的指针。但如果我们对这个子进程 是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可 以设定这个参数为 NULL,就象下面这样:
pid = wait(NULL);
如果成功,wait 会返回被收集的子进程的进程 ID,如果调用进程没有子进程,调用就会失败,此时 wait 返回 -1,同时 errno 被置为 ECHILD。
- wait 系统调用会使父进程暂停执行,直到它的一个子进程结束为止。
- 返回的是子进程的 PID,它通常是结束的子进程
- 状态信息允许父进程判定子进程的退出状态,即从子进程的 main 函数返回的值或子进程中 exit 语句的退 出码。
- 如果 status 不是一个空指针,状态信息将被写入它指向的位置

4.2 waitpid()函数
#include #include pid_t waitpid(pid_t pid, int *status, int options);
参数:
status:如果不是空,会把状态信息写到它指向的位置,与 wait 一样
options:允许改变 waitpid 的行为,最有用的一个选项是 WNOHANG,它的作用是防止 waitpid 把调用者的执行挂起
返回值:如果成功返回等待子进程的 ID,失败返回-1
对于 waitpid 的 pid 参数的解释与其值有关:
pid == -1 等待任一子进程。于是在这一功能方面 waitpid 与 wait 等效。
pid > 0 等待其进程 I D 与 p i d 相等的子进程。
pid == 0 等待其组 I D 等于调用进程的组 I D 的任一子进程。换句话说是与调用者进程同在一个组的进程。
pid < -1 等待其组 I D 等于 p i d 的绝对值的任一子进程 wait 与 waitpid 区别:
在一个子进程终止前, wait 使其调用者阻塞,而 waitpid 有一选择项,可使调用者不阻塞。
waitpid 并不等待第一个终止的子进程—它有若干个选择项,可以控制它所等待的特定进程。
实际上 wait 函数是 waitpid 函数的一个特例。waitpid(-1, &status, 0);
示例:如下代码会创建100个子进程,但是父进程并没有等待他们结束,所以在父进程退出前会有100个僵尸进程;
#include <stdio.h>
#include <unistd.h>
int main() { int i; pid_t pid; for(i=0; i<100; i++) { pid = fork(); if(pid == 0) break; } if(pid>0) { printf("press Enter to exit..."); getchar(); } return 0;
}
其中一个解决方法即是编写一个SIGCHLD信号处理程序来调用wait/waitpid来等待子进程返回。
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
void wait4children(int signo) { int status; wait(&status);
} int main() { int i; pid_t pid; signal(SIGCHLD, wait4children); for(i=0; i<100; i++) { pid = fork(); if(pid == 0) break; } if(pid>0) { printf("press Enter to exit..."); getchar(); } return 0;
}
所以最佳的方案如下:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h> void wait4children(int signo) { int status; pid_t pid;while(pid=waitpid(-1, &status, WNOHANG) > 0){
//if (WIFEXITED(status))// printf("------------child %d exit %d\n", pid, WEXITSTATUS(status));// else if (WIFSIGNALED(status))// printf("child %d cancel signal %d\n", pid, WTERMSIG(status));
}
} int main() { int i; pid_t pid; signal(SIGCHLD, wait4children); for(i=0; i<100; i++) { pid = fork(); if(pid == 0) break; } if(pid>0) { printf("press Enter to exit..."); getchar(); } return 0;
}
这里使用 waitpid 而不是使用 wait 的原因在于:我们在一个循环内调用 waitpid,以获取 所有已终止子进程的状态。我们必须指定 WNOHANG 选项,它告诉 waitpid 在有尚未终止的子进程 在运行时不要阻塞。我们不能在循环内调用 wait,因为没有办法防止 wait 在正运行的子进程尚 有未终止时阻塞。
相关文章:
嵌入式 Linux 的僵尸进程是什么?
目录 1、什么是僵尸进程? 2、僵尸进程的目的 3、怎么避免僵尸进程? 4、僵尸进程的处理方法 4.1 wait()连接 4.2 waitpid()函数 1、什么是僵尸进程? 首先内核会释放终止进程(调用了 exit …...
【刷题笔记】笔记一
1.自守数牛客链接解析:1.自守数的结尾肯定是 0,1,5,62.把数字转换为string类(方便比较)3.直接find在s2 里面 使用find查找另一个即可。#include <iostream> #include<string> using namespace …...
浏览器主页被hao123劫持的解决方案
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…...
华为OD机试题 - 热点网络统计(JavaScript)| 含代码编写思路
华为OD机试题 最近更新的博客使用说明本篇题解:热点网络统计题目输入输出描述示例一输入输出示例二输入输出Code解题思路华为OD其它语言版本最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华…...
IT项目经理的自我修养手册
在不断进步的时代,任何岗位职责都是一个责任、权力与义务的综合体,有多大的权力就应该承担多大的责任,有多大的权力和责任应该尽多大的义务,任何割裂开来的做法都会发生问题。那么作为IT项目经理的岗位职责,我大概列举…...
2023年软考中级电子商务设计师考什么?
首先,电子商务设计师属于软考中级,因此难度也不是特别大。但并不是说就完全没有难度,难度还是有的,像上午题一般把基本知识点掌握了,是没什么问题的,重点就在于下午题会比较难。 接下来我们来剖析一下考试…...
现在的00后太强了,几个问题差点给我问懵了
前言 我们公司刚入职一个00后小伙,今天在办公室交流了一下,他问我会不会自动化测试,我说懂一点,然后直接问了我几个自动化测试问题,差点直接给我问懵了! 问题如下: 我们在制定自动化测试实施…...
$3 : 水项目实战 - 水果库存系统
javase知识点复习: final关键字:http://t.csdn.cn/bvFgu 接口的定义,特性,实现,继承:http://t.csdn.cn/tbXl3 异常:http://t.csdn.cn/VlS0Z DAO的概念和角色(设计理念)&a…...
毕业设计 基于STM32单片机无线ZIGBEE智能大棚土壤湿度光照检测
基于STM32单片机无线ZIGBEE智能大棚土壤湿度光照检测1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 STM32F103C8T6核心系统电路设计2.2 光敏采集电路设计2.3 温度采集电路设计3、部分代码展示3.1 读取DS18B20温度值3.2 定时器初始化1、项目简介 选题指导,…...
华为OD机试真题Java实现【相对开音节】真题+解题思路+代码(20222023)
相对开音节 题目 相对开音节构成的结构为辅音+元音(aeiou)+辅音(r除外)+e,常见的单词有bike、cake等。 给定一个字符串,以空格为分隔符,反转每个单词中的字母,若单词中包含如数字等其他非字母时不进行反转。 反转后计算其中含有相对开音节结构的子串个数(连续的子串…...
【C++】30h速成C++从入门到精通(STL容器listvector)
listlist的介绍list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。list与…...
操作系统---存储管理
存储管理 操作系统将外存的文件调入到内存中,以便CPU调用,如果调用的内容不在内存中,则会产生缺页中断;产生缺页中断后,这事需要从外存调数据到内存中,然后CPU接着从断点继续调用内存中的数据;在…...
华为OD机试题 - 好朋友(JavaScript)| 含思路
华为OD机试题 最近更新的博客使用说明本篇题解:好朋友题目输入输出示例一输入输出说明示例二输入输出说明Code解题思路华为OD其它语言版本最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典...
socket本地多进程通信基本使用方法和示例
目录 前言: socket是什么 socket基本原理框图 socket基本函数 1 socket() 函数 2 bind()函数 3 connect()函数 4 listen() 函数 5 accept() 函数 6 read() write() send() recv()函数 7 close()函数 8 字节序转换(hton) 示例代码 …...
Python 算法交易实验51 Step2 Signals 信号生成
说明 不可不读书 先从经典的一些超简单信号开始 使用移动平均指标SMA(算术) 给出了信号的产生方法,还有一些测算结果,反正看起来都是盈利的 首先使用离线方法实验一组结果,然后就使用ADBS来进行类似的处理。 内容 1 原理分析…...
app上架专用软著认证电子版权在主流应用商店的使用说明2023年最新版
软著认证电子版权在主流应用商店的使用说明 目录 一、 华为应用商店 二、 腾讯应用宝 三、 小米开放平台 小米应用提交: 小米游戏提交: 四、 OPPO开放平台 OPPO应用提交: OPPO游戏(App)提交: OPPO小游戏(快应…...
[Mybatis2]Mapper代理开发
文章目录 问题情境 代理开发 遵循的三条原则 1.定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下 2.设置SQL映射文件的namespace属性为Mapper接口的全限定名 3.在Mapper接口中定义方法,方法名就是SQL映射文件中sql…...
第十一届蓝桥杯大赛青少组国赛Python真题2
第十一届蓝桥杯大赛青少组Python 真题 第二题 提示信息: 杨辉三角形,是二项式系数在三角形中的一种几何排列。中国南宋数学家杨辉在 1261 年所著的《详 解九章算法》一书有明确记载。欧洲数学家帕斯卡在 1654 年发现这一规律,所以又叫做帕斯卡…...
创建springboot项目文件报红
目录 一、遇到问题 二、出现这个问题的原因 三、解决办法 三种方法 四、操作步骤 一、遇到问题 创建springboot项目的时候,会发现一些重要文件都变成红色了,但是不影响程序的运行。只是看起来会有点不舒服。 二、出现这个问题的原因 因为这个spr…...
gma 地理空间绘图:(1) 绘制简单的世界地图-3.设置地图框
内容回顾 gma 地理空间绘图:(1) 绘制简单的世界地图-1.地图绘制与细节调整 gma 地理空间绘图:(1) 绘制简单的世界地图-2.设置经纬网 方法 SetFrame(FrameColor ‘black’, FrameWidth 0.6, ShowFrame True, ShowLeft True, ShowBottom True, Sho…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...
