【Linux】—— 进程等待 waitwaitpid
序言:
之前讲过,子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。因此,为了解决这个问题,就需要用到有关 “进程等待” 的基本知识!!!
目录
(一)进程的等待必要性
(二)进程等待的方法
1、wait方法
2、waitpid方法
(三)获取子进程status
1、进程的阻塞等待方式
2、进程的非阻塞等待方式
总结
(一)进程的等待必要性
进程等待通常是指父进程等待子进程的执行完成。当一个进程创建了一个子进程,并希望在子进程执行完成后再继续执行自己的任务时,父进程需要等待子进程的完成。
以下是一些常见的原因和情况,需要进程等待:
-
避免僵尸进程:如果父进程不等待子进程完成而直接退出,子进程可能会成为僵尸进程。僵尸进程是已经完成执行但尚未被父进程回收的子进程。为了避免僵尸进程的产生,父进程需要等待子进程完成并回收子进程的资源
-
父子进程间通信:在使用fork()系统调用创建子进程时,父进程通常需要等待子进程完成,以确保获取子进程的执行结果或处理子进程的退出状态;
-
最后,父进程派给子进程的任务完成的如何,我们需要知道。如,子进程运行完成,结果对还是不对,或者是否正常退出。
因此,我们可以得出进程等待就是:
- 通过系统调用,获取子进程退出码或者退出信号的方式,顺便释放内存问题
(二)进程等待的方法
进程等待可以通过操作系统提供的函数来实现,主要有以下两种方法来进程等待操作:
- waitpid函数:等待指定的子进程完成。可以设置选项参数来指定等待条件。
- wait函数:等待任意一个子进程完成并获取其退出状态。
1、wait方法
遇到新的函数,如果不认识,就先去系统中查询一下:
【说明】
- 返回值:成功返回被等待进程pid,失败返回-1。
- 参数:输出型参数,获取子进程退出状态,不关心则可以设置成为NULL
接下来,通过代码简单的
int main(){pid_t id = fork();if(id == 0){//子进程int cnt = 5;while(cnt){printf("我是子进程,我还活着呢,我还有%dS, pid: %d, ppid%d\n", cnt --, getpid(), getppid());sleep(1);}exit(0);}sleep(10);// 父进程pid_t ret_id = wait(NULL);printf("我是父进程,等待子进程成功, pid: %d, ppid: %d, ret_id: %d\n",getp id(), getppid(), ret_id); sleep(5);}
输出显示:
【解释】
- 上述代码是一个简单的示例,展示了父进程创建子进程,并使用
wait
函数等待子进程完成。
进阶着又有一个问题:那就是父进程在 wait的时候,如果子进程没有退出,那么父进程在干什么呢?
我们把代码改一下看输出结果。代码如下:
int main(){pid_t id = fork();if(id == 0){//子进程int cnt = 5;while(cnt){printf("我是子进程,我还活着呢,我还有%dS, pid: %d, ppid%d\n", cnt --, getpid(), getppid());sleep(1);}exit(0);}// 父进程pid_t ret_id = wait(NULL);printf("我是父进程,等待子进程成功, pid: %d, ppid: %d, ret_id: %d\n",getp id(), getppid(), ret_id); sleep(5);}
输出显示:
2、waitpid方法
wait 和 waitpid 的头文件一样。具体如下:
pid_ t waitpid(pid_t pid, int *status, int options);
返回值:
1、当正常返回的时候waitpid返回收集到的子进程的进程ID;
2、如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
3、 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;
参数:
pid:
1. Pid=-1,等待任一个子进程。与wait等效。
2. Pid>0.等待其进程ID与pid相等的子进程。
status:
1.WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
2.WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)
options:
1.WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。
- 如果子进程已经退出,调用wait/waitpid时,wait/waitpid会立即返回,并且释放资源,获得子进程退出信息。
- 如果在任意时刻调用wait/waitpid,子进程存在且正常运行,则进程可能阻塞。
- 如果不存在该子进程,则立即出错返回。
(三)获取子进程status
- wait和waitpid,都有一个status参数,该参数是一个输出型参数,由操作系统填充。
- 如果传递NULL,表示不关心子进程的退出状态信息。
- 否则,操作系统会根据该参数,将子进程的退出信息反馈给父进程。
- status不能简单的当作整形来看待,可以当作位图来看待,具体细节如下图(只研究status低16比特位)
具体可以向下述这样理解:
判断一个进程是否正常退出,只需要判断是否接收到进程终止信号。大于0,异常退出,有进程终止信号;等于0,正常退出。
代码演示:
int main()
{pid_t id = fork();if(id == 0){//子进程int cnt = 5;while(cnt){printf("我是子进程,我还活着呢,我还有%dS, pid: %d, ppid: %d\n", cnt--, getpid(), getppid());sleep(1);}exit(111);} // 父进程int status =0 ;pid_t ret_id = waitpid(id, &status, 0);printf("我是父进程,等待子进程成功, pid: %d, ppid: %d, ret_id: %d,child exit code: %d, child exit signal: %d\n"\,getpid(), getppid(), ret_id,(status>>8)&0xFF, status & 0x7F);sleep(2);
}
输出结果:
1、进程的阻塞等待方式
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>int main()
{pid_t pid;pid = fork();if(pid < 0){printf("%s fork error\n",__FUNCTION__);return 1;} else if( pid == 0 ){ //childprintf("child is run, pid is : %d\n",getpid());sleep(5);exit(257);} else{int status = 0;pid_t ret = waitpid(-1, &status, 0);//阻塞式等待,等待5Sprintf("this is test for wait\n");if( WIFEXITED(status) && ret == pid ){printf("wait child 5s success, child return code is :%d.\n",WEXITSTATUS(status));}else{printf("wait child failed, return.\n");return 1;}}return 0;
}
输出展示:
此运行结果是子进程正常退出的场景
2、进程的非阻塞等待方式
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include <sys/types.h>5 #include <sys/wait.h>6 7 int main()8 {9 pid_t pid;10 pid = fork();11 if(pid < 0){12 printf("%s fork error\n",__FUNCTION__);13 return 1;14 }else if( pid == 0 ){ //child15 printf("child is run, pid is : %d\n",getpid());16 sleep(5);17 exit(1);18 } else{19 int status = 0;20 pid_t ret = 0;21 do22 {23 ret = waitpid(-1, &status, WNOHANG);//非阻塞式等待24 if( ret == 0 ){25 printf("child is running\n");26 }27 sleep(1);28 }while(ret == 0);29 if( WIFEXITED(status) && ret == pid ){30 printf("wait child 5s success, child return code is :%d.\n",WEXITS TATUS(status));31 }else{32 printf("wait child failed, return.\n");33 return 1;34 }35 } 36 return 0;37 }38
输出展示:
调用 waitpid 函数(非阻塞,WNOHANG)父子进程交替打印进行各自的循环,大概 5s 之后子进程, 可以看到子进程由 S+ 变成 Z+。
若WIFEXITED(status)为真---->进程正常退出
若WEXITSTATUS(status)>0---->WEXITSTATUS(status)表示子进程的退出码
总结
以上便是关于进程等待的全部知识了。感谢大家的观看与支持!!!
相关文章:
![](https://img-blog.csdnimg.cn/e2abb68a405c4900890ce7ad27f92e61.gif)
【Linux】—— 进程等待 waitwaitpid
序言: 之前讲过,子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。因此,为了解决这个问题,就需要用到有关 “进程等待” 的基本知识!!&am…...
![](https://www.ngui.cc/images/no-images.jpg)
el-tree 懒加载数据,增删改时局部刷新实现
1.数据过多时进行懒加载孩子节点,根据层级传参获取后端孩子数据 懒加载主要部分: 1参数: :load"loadNode" lazy :props"defaultProps" 2.defaultProps 需要设置isLeaf: isLeaf,去除最后一层孩子节点的展开图表 defaultProps: { ch…...
![](https://img-blog.csdnimg.cn/91dc6099b7ea4d00a30d747b3b68f4f4.png)
opencv基础44- Canny边缘检测详解-cv.Canny()
什么是Canny边缘检测? Canny边缘检测是一种经典的边缘检测算法,由John F. Canny在1986年提出。它被广泛应用于计算机视觉和图像处理领域,是一种多阶段的边缘检测算法,能够有效地检测图像中的边缘并抑制噪声。 Canny边缘检测的主要…...
![](https://www.ngui.cc/images/no-images.jpg)
neo4j查询语言Cypher详解(三)--函数
函数 Cypher中的函数如果输入参数为null,则返回null。 以字符串作为输入的函数都对Unicode字符进行操作,而不是对标准字符进行操作。例如,size()函数应用于任何Unicode字符将返回1,即使该字符不适合一个字符的16位。 可以通过 …...
![](https://img-blog.csdnimg.cn/a93db62b11714cc080269e30acf77ca2.jpeg#pic_center)
kafka权威指南(阅读摘录)
零复制 Kafka 使用零复制技术向客户端发送消息——也就是说,Kafka 直接把消息从文件(或者更确切地说是 Linux 文件系统缓存)里发送到网络通道,而不需要经过任何中间缓冲区。这是 Kafka 与其他大部分数据库系统不一样的地方&#…...
![](https://img-blog.csdnimg.cn/img_convert/333830dc257ed5dd5dfebebbc19d7f06.png)
【爬虫实践】使用Python从网站抓取数据
一、说明 本周我不得不为客户抓取一个网站。我意识到我做得如此自然和迅速,分享它会很有用,这样你也可以掌握这门艺术。【免责声明:本文展示了我的抓取做法,如果您有更多相关做法请在评论中分享】 二、计划策略 2.1 策划 确定您…...
![](https://img-blog.csdnimg.cn/66c3f84010f24e1d8382bebf16b0cc8e.png)
win10 2022unity设置中文
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言解决方法 前言 在Edit->preferences里找不到language选项。 解决方法 【1】打开下面地址 注意 :把{version}换成你当前安装的版本,比如说如果…...
![](https://img-blog.csdnimg.cn/img_convert/0fe24b7aa520bdaa8d0d580894553454.png)
python表白代码大全可复制,python表白代码大全简单
大家好,小编来为大家解答以下问题,python表白代码大全可复制,python表白程序代码完整版,现在让我们一起来看看吧! 今天是20230520,有人说:5代表的是人生五味,酸甜苦辣咸;…...
![](https://img-blog.csdnimg.cn/4fd7ccd054f64bbdafea35970da66b44.png)
wordpress 打开缓慢处理
gravatar.com 头像网站被墙 追踪发现请求头像时长为21秒 解决方案一 不推荐,容易失效,网址要是要稳定为主,宁愿头像显示异常,也不能网址打不开 网上大部分搜索到的替换的CDN网址都过期了,例如:gravatar.du…...
![](https://img-blog.csdnimg.cn/849e5340b4e3434a93e0946fe6276476.png)
Adobe ColdFusion 反序列化漏洞复现(CVE-2023-29300)
0x01 产品简介 Adobe ColdFusion是美国奥多比(Adobe)公司的一套快速应用程序开发平台。该平台包括集成开发环境和脚本语言。 0x02 漏洞概述 Adobe ColdFusion存在代码问题漏洞,该漏洞源于受到不受信任数据反序列化漏洞的影响,攻击…...
![](https://img-blog.csdnimg.cn/371bd8ba99744572b7c0eff19a626e73.png)
林【2018】
关键字: BST插入叶子结点、ADT结伴操作、队列插入前r-1、哈希函数二次探测法(1,-1,4,-4)、队列元素个数、折半查找失败次数、广义表链表结构、B-树构建、单链表指定位置插入数组元素 一、判断 二、单选 h(49)+1,-1,+4,-4...
![](https://img-blog.csdnimg.cn/9a481f1af1474d92846cff35f8ac3ac8.png)
ffmpeg+nginx实现rtsp协议摄像头web端播放
ffmpegnginx实现rtsp协议摄像头web端播放 环境准备准备nginx环境添加rtmp模块添加hls转发 使用ffmpeg,将摄像头rtsp转为rtmp并推送到nginxVLC播放验证 环境准备 nginx(需要安装rtmp模块)ffmpeg 6.0vlc播放器(本地播放验证&#x…...
![](https://www.ngui.cc/images/no-images.jpg)
【周赛第69期】满分题解 软件工程选择题 枚举 dfs
目录 选择题1.2.3.4.面向对象设计七大原则 编程题S数最小H值 昨晚没睡好,脑子不清醒,痛失第1名 选择题 1. 关于工程效能,以下哪个选项可以帮助提高团队的开发效率? A、频繁地进行代码审查 B、使用自动化测试工具 C、使用版本控…...
![](https://www.ngui.cc/images/no-images.jpg)
P2015 二叉苹果树
P2015 二叉苹果树 类似于带限制背包问题,但不知道也能做。 n , q n,q n,q 范围小,大胆设 dp 状态。设 f u , i \large f_{u,i} fu,i 表示 u u u 子树内保留 i i i 根树枝的最大苹果数,可得状态转移方程 f u , i f u , j f v , i − …...
![](https://www.ngui.cc/images/no-images.jpg)
Linux 内核音频数据传递主要流程
Linux 用户空间应用程序通过声卡驱动程序(一般牵涉到多个设备驱动程序)和 Linux 内核 ALSA 框架导出的 PCM 设备文件,如 /dev/snd/pcmC0D0c 和 /dev/snd/pcmC0D0p 等,与 Linux 内核音频设备驱动程序和音频硬件进行数据传递。PCM 设…...
![](https://www.ngui.cc/images/no-images.jpg)
torch.device函数
torch.device 是 PyTorch 中用于表示计算设备(如CPU或GPU)的类。它允许你在代码中指定你希望在哪个设备上执行张量和模型操作,本文主要介绍了 torch.device 函数的用法和功能。 本文主要包含以下内容: 1.创建设备对象2.将张量和模…...
![](https://img-blog.csdnimg.cn/img_convert/15bd2f6901978390882403a475d43d63.jpeg)
火车头采集器AI伪原创【php源码】
大家好,本文将围绕python作业提交什么文件展开说明,python123怎么提交作业是一个很多人都想弄明白的事情,想搞清楚python期末作业程序需要先了解以下几个事情。 火车头采集ai伪原创插件截图: I have a python project, whose fold…...
![](https://www.ngui.cc/images/no-images.jpg)
Python中常见的6种数据类型
数字(Numbers):数字类型用于表示数值,包括整数(int)和浮点数(float)。 字符串(Strings):字符串类型用于表示文本,由一系列字符组成。字…...
![](https://img-blog.csdnimg.cn/5f88574f663d45e7b7ed8c53c6b2ab3c.png)
消息队列项目(2)
我们使用 SQLite 来进行对 Exchange, Queue, Binding 的硬盘保存 对 Message 就保存在硬盘的文本中 SQLite 封装 这里是在 application.yaml 中来引进对 SQLite 的封装 spring:datasource:url: jdbc:sqlite:./data/meta.dbusername:password:driver-class-name: org.sqlite.…...
![](https://img-blog.csdnimg.cn/c027e1c4d0a6460383b36563b45c5f8b.png)
解决MAC M1处理器运行Android protoc时出现的错误
Protobuf是Google开发的一种新的结构化数据存储格式,一般用于结构化数据的序列化,也就是我们常说的数据序列化。这个序列化协议非常轻量级和高效,并且是跨平台的。目前,它支持多种主流语言,比传统的XML、JSON等方法更具…...
![](https://www.ngui.cc/images/no-images.jpg)
C#使用SnsSharp实现鼠标键盘钩子,实现全局按键响应
gitee下载地址:https://gitee.com/linsns/snssharp 一、键盘事件,使用SnsKeyboardHook 按键事件共有3个: KeyDown(按键按下) KeyUp(按键松开) KeyPress(按键按下并松开) 以KeyDown事件为例,使用代码如下&…...
![](https://img-blog.csdnimg.cn/8530de22c0f14dc28c41fc620fe51d19.png)
Zookeeper基础操作
搭建Zookeeper服务器 windows下部署 下载地址: https://mirrors.cloud.tencent.com/apache/zookeeper/zookeeper-3.7.1/ 修改配置文件 打开conf目录,将 zoo_sample.cfg复制一份,命名为 zoo.cfg打开 zoo.cfg,修改 dataDir路径,…...
![](https://img-blog.csdnimg.cn/aef53c9eb54e4b40bb6fb14a1aba23c2.png)
【CSS】说说响应式布局
目录 一、是什么 二、怎么实现 1、媒体查询 2、百分比 3、vw/vh 4、小结 三、总结 一、是什么 响应式设计简而言之,就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。 响应式网站常见特点: 同时适配PC 平板 手机等…...
数据结构 | 利用二叉堆实现优先级队列
目录 一、二叉堆的操作 二、二叉堆的实现 2.1 结构属性 2.2 堆的有序性 2.3 堆操作 队列有一个重要的变体,叫作优先级队列。和队列一样,优先级队列从头部移除元素,不过元素的逻辑顺序是由优先级决定的。优先级最高的元素在最前ÿ…...
![](https://www.ngui.cc/images/no-images.jpg)
Javascript怎样阻止事件传播?
在 JavaScript 中,可以使用事件对象的方法来阻止事件传播。事件传播指的是当一个元素上触发了一个事件,该事件会在事件流中传播到父元素或祖先元素,从而影响到它们。 事件传播有三个阶段:捕获阶段、目标阶段和冒泡阶段。阻止事件…...
![](https://img-blog.csdnimg.cn/2c3b420acb1444b29765130f0b10bc4b.png)
web-csrf
目录 CSRF与XSS的区别: get请求 原理: pikachu为例 post请求 pikachu为例 CSRF与XSS的区别: CSRF是借用户的权限完成攻击,攻击者并没有拿到用户的权限,而XSS是直接盗取到了用户的权限 get请求 原理:…...
![](https://img-blog.csdnimg.cn/24dc885ce3d64f8c87f1b617824ea879.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWVtb3Jpc2UxOTk5,size_20,color_FFFFFF,t_70,g_se,x_16)
数据结构—图的存储结构
6.图 回顾:数据的逻辑结构 集合——数据元素间除 “同属于一个集合” 外,无其他关系。 线性结构——一个对一个,如线性表、栈、队列 树形结构——一个对多个,如树 图形结构——多个对多个,如图 6.1图的定义和术语 图:…...
![](https://www.ngui.cc/images/no-images.jpg)
Vue3 中 setup,ref 和 reactive 的理解
setup Vue3中使用了Composition API这种写法,使得所有的组合API函数都在此使用, 只在初始化时执行一次。 函数如果返回对象, 对象中的属性或方法, 模板中可以直接使用 ref 作用:定义一个数据的响应式 语法:const xxx ref(initValue) 一般用来…...
![](https://img-blog.csdnimg.cn/img_convert/d21952e94db9fcd601ff7acad54f1b29.png)
BL302嵌入式ARM控制器进行SQLite3数据库操作的实例演示
本文主要讲述了在钡铼技术BL302嵌入式arm控制器上运行 SQLite3 数据库的命令示例。SQLite3 是一个轻型的嵌入式数据库,不需要安装数据库服务器进程,占用资源低且处理速度快。 首先,需要将对应版本的 SQLite3 文件复制到设备的 /usr/ 目录下&…...
![](https://img-blog.csdnimg.cn/e6fc5c387cf24543b53a68e1c449bd7a.png)
C++ 多线程:std::future
std::future std::future 简介示例1博客引用来源 std::future 简介 我们前面介绍的std::thread 是C11中提供异步创建多线程的工具,只能是异步运行任务,却无法获取任务执行的结果,一般都是依靠全局对象,全局对象在多线程下是及其不…...
![](/Images/OutliningIndicators/None.gif)
网站怎么做才能上百度首页/友情链接联盟
Hibernate中进行数据库增删改的代码,太多不想背了,记在这里以后来查好啦~~~~packageorg.lxh.hibernate.demo01;importjava.util.Iterator;importjava.util.List;importorg.hibernate.Query;importorg.hibernate.Session;importorg.hibernate.SessionFact…...
![](/images/no-images.jpg)
重庆石桥铺网站建设公司/网站关键词快速排名优化
将 Game over2.wav改为Log-in-long2.wav 这个是登录界面的音乐将 main_theme.wav改为sellect-loop2.wav 这个是角色选择界面的音乐最好先将Log-in-long2.wav sellect-loop2.wav这两个文件改成别的名字,以免更改的时候说有文件重名 WAV文件夹里面还有一首32.21M…...
![](/images/no-images.jpg)
网站定制论文1500字左右/推广公司产品
问题:我在视图画的图象或者文字,当窗口改变后为什么不见了?OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同? 答:OnDraw()和OnPaint()好象兄弟俩,因为它们的工作类似。至于不见了的问题…...
![](https://img-blog.csdnimg.cn/img_convert/f6e1681a7eef6fd21327a1161700fc19.png)
网站焦点图怎么做/如何做好网络推广销售
基于集成学习的用户流失预测并利用shap进行特征解释 小P:小H,如果我只想尽可能的提高准确率,有什么好的办法吗? 小H:优化数据、调参侠、集成学习都可以啊 小P:什么是集成学习啊,听起来就很厉害的…...
![](/images/no-images.jpg)
手机网站建设是什么/百度一下你就知道手机版官网
本文主要总结线程共享数据的相关知识,主要包括两方面:一是某个线程内如何共享数据,保证各个线程的数据不交叉;一是多个线程间如何共享数据,保证数据的一致性。线程范围内共享数据自己实现的话,是定义一个Map,线程为键&…...
![](/images/no-images.jpg)
建筑工程网 装修/seo简介
本文已迁移至:https://blog.csdn.net/COCO56/article/details/100041476...