wait/waitpid函数使用

waitpid函数详解+应用示例 来源:微信公众号「编程学习基地」 文章目录waitpid函数的使用waitpid()函数定义参数详解使用示例 waitpid函数的使用 当用fork启动一个新的子进程的时候,子进程就有了新的生命周期,并将在其自己的地址空间内独立运行。但有的时候,我们希望知道某一个自己创建的子进程何时结束,从而方便父进程做一些处理动作。 waitpid()函数定义 先来看看waitpid函数的定义: #include <sys/types.h> #include <sys/wait.h> .. 阅读详情

僵尸进程: 子进程退出,父进程没有回收子进程资源(PCB),则子进程变成僵尸进程
孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为1号进程init进程,称为init进程领养孤儿进程

       #include <sys/types.h>
       #include <sys/wait.h>

       pid_t wait(int *status);
       pid_t waitpid(pid_t pid, int *status, int options);

一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中保存了一些信息:如果是正常终止则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是哪个。这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除掉这个进程。我们知道一个进程的退出状态可以在Shell中用特殊变量$?查看,因为Shell是它的父进程,当它终止时Shell调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程。
如果一个进程已经终止,但是它的父进程尚未调用wait或waitpid对它进行清理,这时的进程状态称为僵尸(Zombie)进程。任何进程在刚终止时都是僵尸进程,正常情况下,僵尸进程都立刻被父进程清理了,为了观察到僵尸进程,我们自己写一个不正常的程序,父进程fork出子进程,子进程终止,而父进程既不终止也不调用wait清理子进程:

#include <unistd.h>
#include <stdlib.h>

int main(void)
{
pid_t pid=fork();
if(pid<0) {
perror("fork");
exit(1);
}
if(pid>0) { /* parent */
while(1);
}
/* child */
return 0;
}

查看进程:

cat       2751 99.2  0.0   2008   284 pts/1    R+   23:46   0:16 ./fork
cat       2752  0.0  0.0      0     0 pts/1    Z+   23:46   0:00 [fork] <defunct>

可以看到子进程的状态已经变成Z+即僵尸态了。

wait/waitpid若调用成功则返回清理掉的子进程id,若调用出错则返回-1。父进程调用wait或waitpid时可能会:

  • 阻塞(如果它的所有子进程都还在运行)。
  • 带子进程的终止信息立即返回(如果一个子进程已终止,正等待父进程读取其终止信息)。
  • 出错立即返回(如果它没有任何子进程)。

这两个函数的区别是:
如果父进程的所有子进程都还在运行,调用wait将使父进程阻塞,而调用waitpid时如果在options参数中指定WNOHANG可以使父进程不阻塞而立即返回0。
wait等待第一个终止的子进程,而waitpid可以通过pid参数指定等待哪一个子进程。可见,调用wait和waitpid不仅可以获得子进程的终止信息,还可以使父进程阻塞等待子进程终止,起到进程间同步的作用。如果参数status不是空指针,则子进程的终止信息通过这个参数传出,如果只是为了同步而不关心子进程的终止信息,可以将status参数指定为NULL。
例 waitpid

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid < 0) {
perror("fork failed");
exit(1);
}
if (pid == 0) {
int i;
for (i = 10; i > 0; i--) {
printf("This is the child\n");
sleep(1);
}
exit(3);
} else {
int stat_val;
waitpid(pid, &stat_val, 0);
if (WIFEXITED(stat_val))
printf("Child exited with code %d\n", WEXITSTATUS(stat_val));
else if (WIFSIGNALED(stat_val))
printf("Child terminated abnormally, signal %d\n", WTERMSIG(stat_val));
}
return 0;
}

结果:

cat@lenovo:~/blog/0724$ ./test
This is the child
This is the child
This is the child
This is the child
This is the child
This is the child
This is the child
This is the child
Child terminated abnormally, signal 9
...
This is the child
This is the child
This is the child
Child exited with code 3

waitpid pid值的4种情况:

  • <-1 回收指定进程组内的任意子进程
  • -1 回收任意子进程
  • 0 回收和当前调用waitpid一个组的所有子进程
  • >0 回收指定ID的子进程

用于检查wait和waitpid两个函数返回终止状态的宏:
这两个函数返回的子进程状态都保存在statloc指针中, 用以下3个宏可以检查该状态:

  • WIFEXITED(status): 若为正常终止, 则为真. 此时可执行
    • WEXITSTATUS(status): 取子进程传送给exit或_exit参数的低8位.
  • WIFSIGNALED(status): 若为异常终止, 则为真. 此时可执行
    • WTERMSIG(status): 取使子进程终止的信号编号.
  • WIFSTOPPED(status): 若为当前暂停子进程, 则为真. 此时可执行
    • WSTOPSIG(status): 取使子进程暂停的信号编号.
Linux系统编程——僵尸进程及wait/waitpid函数 一般来说,当父进程fork()了一个子进程之后,它有义务把子进程回收。但如果子进程运行完毕后,父进程尚未回收,此时的子进程残留信息(PCB)存放于内核中,变成僵尸进程。(若父进程先于子进程结束,则子进程成为孤儿进程。) 我们知道,子进程的结束和父进程的运行是异步的,那么,父进程会不会不知道子进程已经结束了呢?UNIX中存在一种机制,一个进程调用exit()来结束自己的生命,内核释放该进程所 阅读详情

相关推荐

宇树机器人丝滑的二人转动作背后,MPC到底是什么?

了解MPC,让我们闻“机”起舞。

Barok的博客 2146

waitpid()函数详解

一、前言 首先在了解waitpid()函数之前,我们需要先明确以下几个概念。 1.进程状态 从程序员的角度,我们可以认为进程总是处于下面三种状态之一: (1)运行。进程要么在CPU上执行,要么在等待被执行且最终会被内核调度。 (2)停止。进程的执行被挂起(suspended),且不会被调度。当收到SIGSTOP、SIGTSTP、SIGTTIN或者SIGTTOU信号时,进程就停止,并且保持停止直到他收到一个SIGCONT信号,在这个时刻,进程再次开始运行。 (3)终止。进程永远的停...

weixin_45227610的博客 2万+

上、下拉电阻(定义、强弱上拉、常见作用、吸电流、拉电流、灌电流)

1.上、下拉电阻定义 上拉电阻是把一个信号通过一个电阻接到电源(Vcc),下拉电阻是一个信号通过一个电阻接到地(GND)。 2.强上拉、弱上拉 强上拉、弱上拉的强弱只是上拉电阻的阻值不同,没有什么严格区分。例如:50Ω上拉,一般成为强上拉;100kΩ上拉则称为弱上拉。下拉也是一样的。强拉电阻的极端就是0Ω电阻,即将信号线直接与电源或低相连接。 3.上、下拉电阻的作用 因为上下拉电阻的作用概念很宽泛,不用领域的使用方法也不同,常见使用方法整理如下: ...

小浪宝宝的博客 3万+

进程等待函数(waitpid)

waitpid函数原型如下: pid_t waitpid(pid_t pid , int *status , int options) 与wait函数相比,系统调用二者的作用是完全相同的,但是waitpid多出了两个可由用户控制的参数pid和options。 pid:从参数的名字上可以看出来这是一个进程的ID。但是这里pid的值不同时,会有不同的意义。 1.pid > 0时,只等待进程ID等于pid的子进程,只要该子进程不结束,就会一直等待下去; 2.pid = -1时,等待任何一个子进程的退出,此时

mlc741295821的博客 9214

【图神经网络】从0到1使用PyG手把手创建异构图

异构图的准确定义如下:异构图(Heterogeneous Graphs):一个异构图GGG有一组节点V=v1,v2,...,vnV=v_1,v_2,...,v_nV=v1​,v2​,...,vn​和一组边E=e1,e2,...,emE=e_1,e_2,...,e_mE=e1​,e2​,...,em​组成,其中每个节点和每条边都对应着一种类型,用TvT_vTv​表示节点类型的集合,TeT_eTe​表示边类型的集合,一个异构图有两个映射函数,分别将每个节点映射到其对应的类型ϕv:V→Tv\phi_v:V\rig

小哲的博客 7833

rk3568 android 11.0 userdata 改为ext4格式

功能:解决设备在恢复出厂设置进行擦除数据的时候卡住问题。 1.修改userdata分区为ext4格式 diff --git a/device/rockchip/common/scripts/fstab_tools/fstab.in b/device/rockchip/common/scripts/fstab_tools/fstab.in index 583e75579d..036336835d 100755 --- a/device/rockchip/common/scripts/fstab_tools/

chgh1306的专栏 2576

linux多进程基础(3):waitpid()函数

linux多进程基础(3):waitpid()函数

shnhe的博客 1063

舵机PWM信号转互斥继电器开关信号

-----------------本文由“麦粒电子”撰写,并提供相应产品服务。---------------- 叙述 上次的PWM转继电器开关方案得到大家的不少好评(博客链接),但是发现有些玩家需要一路PWM同时去控制两路继电器开关通断,并且两者是互斥的,好去控制两种不同的负载。所以就继续升级了如下的模块。 正常的控制部件顺序这样:遥控器按钮拨动,遥控器接收机相应通道PWM值变化,PWM转开关模块检测PWM值发生变化从而驱动相应机械继电器触点吸合释放。本模块的两个继电器动作是互斥的,也就是不会同时吸合。

Mai_LiElectronic的博客 1634

Linux系统调用之wait,waitpid函数(进程相关函数)

如果,想要深入的学习Linux系统调用中的wait,waitpid函数,还是需要去自己阅读Linux系统中的帮助文档。具体输入命令:即可查阅到完整的资料信息。

weixin_49503250的博客 2616

医疗影像处理实战:如何用Slicer和Mimics将.nii.gz文件转为.ply格式(附避坑指南)

本文详细介绍了利用3D Slicer和Materialise Mimics软件,将医学影像中常见的.nii.gz格式文件转换为通用三维网格.ply格式的完整实战流程。文章重点分享了从数据分割、DICOM序列导出到高质量网格生成的核心步骤与关键参数设置,并提供了针对常见问题的避坑指南,旨在帮助医学影像研究者和工程师高效完成从体数据到三维模型的关键转换。

weixin_28304023的博客 103

UE5.5使用ControlRig实现MetaHumanNPC看向玩家

本文介绍了在虚幻引擎中实现NPC自然看向玩家的技术方案。通过MetaHuman的ControlRig系统,采用面部动画曲线+全身动画Montage的表演方式,结合ControlRig驱动CTRL_lookat控制器实现视线追踪。

平常心 1303

wait/waitpid函数

父进程查询子进程的退出状态可以用wait/waitpid函数。 wait系统调用会使父进程暂停执行直到它的一个子进程结束为止。 返回的是子进程的PID,它通常是结束的子进程 状态信息允许父进程判定子进程的退出状态,即从子进程的main函数返回的值或子进程中exit语句的退出码。 如果status不是一个空指针,状态信息将被写入它指向的位置。 宏定义 描述 WIFEXITED(s...

m0_38036750的博客 645

基于Blender的AI插件——2D图片生成3D模型

只需5分钟即可从图片到可编辑3D模型,支持Blender全版本兼容。

这里汇聚了前沿的技术分享与实用的开发技巧,带你探索从创意到企业的技术创业之路。 2577

进程exec函数簇与wait/waitpid函数

1,被加载的文件的参数列表必须以自身名字为开始,以 NULL 为结尾。比如要加载执 行当前目录下的一个叫做 a.out 的文件,需要一个参数”abcd”,那么正确的调用应该是: execl(“./a.out”, “a.out”, “abcd”, NULL); 或者: const char *argv[3] = {“a.out”, “abcd”, NULL}; execv(“./a.out”, a...

weixin_44522306的博客 401

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

wait/waitpid函数详解

#include<sys/types.h> #include<sys/wait.h> pid_t wait(int *status); pid_t waitpid(pid_t pid, int *status, int options); 特殊参数和返回情况: 参数pid: >0 回收指定ID的子进程 -1 回收任意子进程(相当于wait...

qq_25048473的博客 1484

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

嵌入式学习---进程借宿函数wait/waitpid,以及线程相关

非阻塞:父进程会查看子进程状态,当子进程没有状态改变时,父进程会执行自己的任务,等待下一次再来查看(故使用非阻塞时要写入循环)@retval //退出状态值 //传的是,退出状态值 对应的地址。@start_routine -- 线程执行函数 (线程回调函数)//注: 线程回调函数 --完成线程任务功能的函数。//在那个线程中调用,获得的就是那个线程的tid。@retval --- 用来保存,退出状态值,所在空间的地址。options//选项有两种,默认是填0,表示默认,会造成阻塞效果。

xufenglinger的博客 413

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

wait/waitpid函数等待子进程状态发生改变

wait函数与waitpid函数如何终止进程,这两个函数用来等待某个(些)子进程的状态发生改变,进程等待有几种状态,函数参数的解释,与宏定义的相关关系,使用wait/waitpid函数的代码实例。

勾栏听曲_0的博客 8766

进程管理(vfork exec函数族 wait/waitpid)

fork与vfork的区别(1)fork子进程拷贝父进程的数据段,vfork子进程与父进程共享数据段。(2)fork父、子进程的执行次序不确定,vfork子进程先运行,父进程后运行。(3)vfork有限制,子进程必须立刻执行_exit或者exec函数。进程终止的方式exec函数族wait/waitpid...

Cyber 588

fork函数和wait/waitpid函数

复制一个进程映象fork 使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等。 子进程与父进程的区别在于: 1、父进程设置的锁,子进程不继承 2、各自的进程ID和父进程ID不同 3、子进程的未决告警被清除; 4、子进程的未决信号集设置为空集

qq_25048473的博客 3873

linux的wait/waitpid和exec/execv函数

wait #include <sys/types.h> /* 提供类型pid_t的定义 */ #include <sys/wait.h> pid_t wait(int *status) 进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回; 如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。 参数status用来.

$好记性还是要多记录$ 735

Linux进程 -- wait/waitpid函数

僵尸进程: 子进程退出,父进程没有回收子进程资源(PCB),则子进程变成僵尸进程。 孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为1号进程init进程。wait/waitpid函数函数原型:#include <sys/types.h> #include <sys/wait.h>pid_t wait(int *status); pid_t waitpid(pid_t pi

未来之歌 2164

进程等待----wait函数/waitpid函数

通过系统调用。

2403_82706967的博客 1058

Linux 回收子进程 wait/waitpid函数

wait/waitpid函数 前提 一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的 PCB 还保留着,内核在其中保存了一些信息:如果是正常终止则保存着退出状态,如果是异常终 止则保存着导致该进程终止的信号是哪个。这个进程的父进程可以调用 wait 或 waitpid 获取这些信息,然后彻底清除掉这个进程。我们知道一个进程的退出状态可以在 Shell 中用特殊变量$?查看,因为 Shell 是它的父进程,当它终止时 Shell 调用 wait 或 waitpid 得到它的退出状态同时彻

阿渌的博客札记 483

linux waitpid/wait函数用法

关于linux中waitpid函数的一些使用说明: #includesys/types.h>     #include     定义函数 pid_t waitpid(pid_t pid,int * status,int options); waitpid函数有三个参数:pid和指向返回状态所在单元的指针和一个用来指定可选项的标识符。如果pid为-1 ,waitpid就等待任

hunanchenxingyu的专栏 2526

《Linux系统编程篇》fork/wait/waitpid/exit函数——基础篇

在 Linux 中,所有的进程都是通过 fork() 派生而来。当一个进程调用 fork() 时,操作系统会复制当前进程的上下文,为它创建一个几乎完全相同的副本,这个副本被称为子进程,而原始进程被称为父进程。这也是人们口中的父子进程的概念。

Strange_Head的博客 1813

Linux中孤儿/僵尸进程/wait/waitpid函数

概念:若子进程的父进程已经死掉,而子进程还存活着,这个进程就成了孤儿进程。

luosuss的博客 1171
上一篇: gdb调试工具的使用
下一篇: django1.8使用mysql数据库
Linux_forker
博客等级 码龄11年 3粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值