当前位置: 首页 > news >正文

嵌入式 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。

  1. wait 系统调用会使父进程暂停执行,直到它的一个子进程结束为止。
  2. 返回的是子进程的 PID,它通常是结束的子进程
  3. 状态信息允许父进程判定子进程的退出状态,即从子进程的 main 函数返回的值或子进程中 exit 语句的退 出码。
  4.  如果 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、什么是僵尸进程&#xff1f; 2、僵尸进程的目的 3、怎么避免僵尸进程&#xff1f; 4、僵尸进程的处理方法 4.1 wait&#xff08;&#xff09;连接 4.2 waitpid&#xff08;&#xff09;函数 1、什么是僵尸进程&#xff1f; 首先内核会释放终止进程(调用了 exit …...

【刷题笔记】笔记一

1.自守数牛客链接解析&#xff1a;1.自守数的结尾肯定是 0&#xff0c;1&#xff0c;5&#xff0c;62.把数字转换为string类&#xff08;方便比较&#xff09;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项目经理的自我修养手册

在不断进步的时代&#xff0c;任何岗位职责都是一个责任、权力与义务的综合体&#xff0c;有多大的权力就应该承担多大的责任&#xff0c;有多大的权力和责任应该尽多大的义务&#xff0c;任何割裂开来的做法都会发生问题。那么作为IT项目经理的岗位职责&#xff0c;我大概列举…...

2023年软考中级电子商务设计师考什么?

首先&#xff0c;电子商务设计师属于软考中级&#xff0c;因此难度也不是特别大。但并不是说就完全没有难度&#xff0c;难度还是有的&#xff0c;像上午题一般把基本知识点掌握了&#xff0c;是没什么问题的&#xff0c;重点就在于下午题会比较难。 接下来我们来剖析一下考试…...

现在的00后太强了,几个问题差点给我问懵了

前言 我们公司刚入职一个00后小伙&#xff0c;今天在办公室交流了一下&#xff0c;他问我会不会自动化测试&#xff0c;我说懂一点&#xff0c;然后直接问了我几个自动化测试问题&#xff0c;差点直接给我问懵了&#xff01; 问题如下&#xff1a; 我们在制定自动化测试实施…...

$3 : 水​​​​​项目实战 - 水果库存系统

javase知识点复习&#xff1a; final关键字&#xff1a;http://t.csdn.cn/bvFgu 接口的定义&#xff0c;特性&#xff0c;实现&#xff0c;继承&#xff1a;http://t.csdn.cn/tbXl3 异常&#xff1a;http://t.csdn.cn/VlS0Z DAO的概念和角色&#xff08;设计理念&#xff09;&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、项目简介 选题指导&#xff0c…...

华为OD机试真题Java实现【相对开音节】真题+解题思路+代码(20222023)

相对开音节 题目 相对开音节构成的结构为辅音+元音(aeiou)+辅音(r除外)+e,常见的单词有bike、cake等。 给定一个字符串,以空格为分隔符,反转每个单词中的字母,若单词中包含如数字等其他非字母时不进行反转。 反转后计算其中含有相对开音节结构的子串个数(连续的子串…...

【C++】30h速成C++从入门到精通(STL容器listvector)

listlist的介绍list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素。list与…...

操作系统---存储管理

存储管理 操作系统将外存的文件调入到内存中&#xff0c;以便CPU调用&#xff0c;如果调用的内容不在内存中&#xff0c;则会产生缺页中断&#xff1b;产生缺页中断后&#xff0c;这事需要从外存调数据到内存中&#xff0c;然后CPU接着从断点继续调用内存中的数据&#xff1b;在…...

华为OD机试题 - 好朋友(JavaScript)| 含思路

华为OD机试题 最近更新的博客使用说明本篇题解:好朋友题目输入输出示例一输入输出说明示例二输入输出说明Code解题思路华为OD其它语言版本最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典...

socket本地多进程通信基本使用方法和示例

目录 前言&#xff1a; socket是什么 socket基本原理框图 socket基本函数 1 socket() 函数 2 bind()函数 3 connect()函数 4 listen() 函数 5 accept() 函数 6 read() write() send() recv()函数 7 close()函数 8 字节序转换&#xff08;hton&#xff09; 示例代码 …...

Python 算法交易实验51 Step2 Signals 信号生成

说明 不可不读书 先从经典的一些超简单信号开始 使用移动平均指标SMA(算术&#xff09; 给出了信号的产生方法&#xff0c;还有一些测算结果&#xff0c;反正看起来都是盈利的 首先使用离线方法实验一组结果&#xff0c;然后就使用ADBS来进行类似的处理。 内容 1 原理分析…...

app上架专用软著认证电子版权在主流应用商店的使用说明2023年最新版

软著认证电子版权在主流应用商店的使用说明 目录 一、 华为应用商店 二、 腾讯应用宝 三、 小米开放平台 小米应用提交&#xff1a; 小米游戏提交&#xff1a; 四、 OPPO开放平台 OPPO应用提交: OPPO游戏&#xff08;App&#xff09;提交: OPPO小游戏&#xff08;快应…...

[Mybatis2]Mapper代理开发

文章目录 问题情境 代理开发 遵循的三条原则 1.定义与SQL映射文件同名的Mapper接口&#xff0c;并且将Mapper接口和SQL映射文件放置在同一目录下 2.设置SQL映射文件的namespace属性为Mapper接口的全限定名 3.在Mapper接口中定义方法&#xff0c;方法名就是SQL映射文件中sql…...

第十一届蓝桥杯大赛青少组国赛Python真题2

第十一届蓝桥杯大赛青少组Python 真题 第二题 提示信息&#xff1a; 杨辉三角形&#xff0c;是二项式系数在三角形中的一种几何排列。中国南宋数学家杨辉在 1261 年所著的《详 解九章算法》一书有明确记载。欧洲数学家帕斯卡在 1654 年发现这一规律&#xff0c;所以又叫做帕斯卡…...

创建springboot项目文件报红

目录 一、遇到问题 二、出现这个问题的原因 三、解决办法 三种方法 四、操作步骤 一、遇到问题 创建springboot项目的时候&#xff0c;会发现一些重要文件都变成红色了&#xff0c;但是不影响程序的运行。只是看起来会有点不舒服。 二、出现这个问题的原因 因为这个spr…...

gma 地理空间绘图:(1) 绘制简单的世界地图-3.设置地图框

内容回顾 gma 地理空间绘图&#xff1a;(1) 绘制简单的世界地图-1.地图绘制与细节调整 gma 地理空间绘图&#xff1a;(1) 绘制简单的世界地图-2.设置经纬网 方法 SetFrame(FrameColor ‘black’, FrameWidth 0.6, ShowFrame True, ShowLeft True, ShowBottom True, Sho…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

深入理解 React 样式方案

React 的样式方案较多,在应用开发初期,开发者需要根据项目业务具体情况选择对应样式方案。React 样式方案主要有: 1. 内联样式 2. module css 3. css in js 4. tailwind css 这些方案中,均有各自的优势和缺点。 1. 方案优劣势 1. 内联样式: 简单直观,适合动态样式和…...