函数wait和waitpid
函数wait
一个进程在终止时会关闭所有文件描述符,释放在用户空间释放的内存,但它的PCB还保留着,内核在其中保存一些信息:如果是正常终止时则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是哪个,这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除这个进程,我们知道一个进程的退出状态可以在shell用特殊变量$?查看,因为shell是它的父进程,当它终止时shell调用wait或waitpid得到它的退出状态同时彻底清除这个进程。
1. 函数wait:一次只能回收一个子进程
pid_t wait(int *status); status传出参数
进程终止时,操作系统隐式回收机制会:1. 关闭所有的文件描述符 2. 释放用户空间分配的内存。内核PCB仍存在,其中保存该进程的退出状态。(正常终止--------退出值;异常终止-------终止信号)
可使用wait函数传出参数status来保存进程的退出状态,借助宏函数来进一步判断进程终止的具体原因,宏函数可分为三组:
- WIFEXITED(status):为非0,进程正常结束;WEXITSTATUS(status) :如上宏为真,使用此宏 获取进程退出状态(exit的参数)
- WIFSIGNALED(status):为非0,进程异常终止;WTERMSIG(status):如上宏为真,使用此宏 获取进程终止的那个信号编号
- WIFSTOPPED(status) :为非0,进程处于暂停状;WSTOPSIG(status):如上宏为真,使用此宏 获取进程暂停的那个信号编号
1. 测试代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h> int main(void)
{
pid_t pid, wpid;
pid = fork(); if(pid == )
{
printf("---child, my parent = %d, going to sleep 10s\n", getpid());
sleep();
printf("---------child die --------------\n");
}
else if(pid > )
{
wpid = wait(NULL);
if(wpid == -)
{
perror("wait error: ");
exit();
}
while()
{
printf("I am parent, pid = %d, my son = %d\n", getpid(), pid);
sleep();
}
}
else
{
perror("fork");
return ;
}
return ;
}
输出结果

1. 测试代码:
#include <stdio.h>
#include <unistd.h>
#include<sys/wait.h> int main(int argc, const char* argv[])
{
pid_t pid = fork(); if (pid > ) // 父进程
{
printf("parent process, pid = %d, ppid = %d\n", getpid(), getppid());
int status;
pid_t wpid = wait(&status); if (WIFEXITED(status))
printf("exit value: %d", WEXITSTATUS(status));
if (WIFSIGNALED(status))
printf("exit by signal: %d\n", WTERMSIG(status)); //是否被信号杀死 printf(" die child pid = %d\n", wpid);
}
else if(pid == )
{
sleep();
printf("child process, pid = %d, ppid = %d\n", getpid(), getppid());
}
for (int i = ; i<; ++i)
printf(" i = %d\n", i);
return ;
}
输出结果:

3. 测试代码:
#include <stdio.h>
#include <unistd.h>
#include<sys/wait.h> int main(int argc, const char* argv[])
{
pid_t pid = fork(); if (pid > ) //父进程
{
printf("parent process, pid = %d, ppid = %d\n", getpid(), getppid());
int status;
pid_t wpid = wait(&status); if (WIFEXITED(status))
printf("exit value: %d", WEXITSTATUS(status));
if (WIFSIGNALED(status))
printf("exit by signal: %d\n", WTERMSIG(status)); //是否被信号杀 printf(" die child pid = %d\n", wpid);
}
else if (pid == )
{
while()
{
sleep();
printf("child process, pid = %d, ppid = %d\n", getpid(), getppid());
}
}
for (int i = ; i<; ++i)
printf(" i = %d\n", i);
return ;
}
采取操作:
pts/ S+ : ./test
pts/ S+ : ./test
pts/ R+ : ps ajx
sunbin@sunbin:~$ kill -
输出结果:

函数waitpid
函数waitpid原型:作用同wait,但可指定pid进程清理,可以不阻塞( 一次只能回收一个子进程)
pid_t wait(pid_t pid, int *staloc, int options);
1. 参数pid:
- pid == -1:回收任一子进程
- pid > 0 :回收指定pid的进程
- pid == 0 :回收与父进程同一个进程组的任一个子进程
- pid < -1 :回收指定进程组内的任意子进程
2. 参数options:
- 设置为WNOHANG:函数不阻塞;
- 设置为0:函数阻塞。
函数wait和waitpid的更多相关文章
- 阻塞进程函数 wait()和waitpid()
1. wait()和waitpid()函数说明 wait() 进程一旦调用了wait(), 就立即阻塞自己,由wait自动分析是否有当前进程的某个子进程已经退出,如果让它找到了一个已经变成僵尸的子进 ...
- wait/waitpid函数与僵尸进程、fork 2 times
一.僵尸进程 当子进程退出的时候,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) 子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程, ...
- 【Linux】僵尸进程,孤儿进程以及wait函数,waitpid函数(有样例,分析很详细)
本文内容: 1.僵尸进程,孤儿进程的定义,区别,产生原因,处理方法 2.wait函数,waitpid函数的分析,以及比较 背景:由于子进程的结束和父进程的运行是一个异步的过程,即父进程永远无法预测子进 ...
- wait函数与waitpid函数(僵尸进程)
当子进程退出时,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) 子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程.它只保留最小的一些 ...
- 父进程等待子进程结束 waitpid wait
我们一直在强调一个概念就是进程是一个程序执行的实例,是内核在虚拟概念下创建的实体,它实例化的体现在用户态就是程序代码和代码使用的变量(存储空间),在内核态就是内核为我们每个进程所保存的数据结构(状态信 ...
- 对于linux下system()函数的深度理解(整理)
原谅: http://blog.sina.com.cn/s/blog_8043547601017qk0.html 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同 ...
- 【转】linux中waitpid及wait的用法
原文网址:http://www.2cto.com/os/201203/124851.html wait(等待子进程中断或结束) 表头文件 #include<sys/types.h> ...
- system函数的总结
最近在看APUE第10章中关于system函数的POSIX.1的实现.关于POSIX.1要求system函数忽略SIGINT和SIGQUIT,并且阻塞信号SIGCHLD的论述,理解得不是很透彻,本文就 ...
- linux中waitpid及wait的用法
wait(等待子进程中断或结束) 表头文件 #include<sys/types.h> #include<sys/wait.h> 定义函数 pid_t wa ...
随机推荐
- Python学习笔记-数字类型
如何定义一个数字类型 定义var1为一个INT类型,所以在5/3 输出的是 1. var1 = 5 var1=var1/3 print var1 定义var1为一个INT类型,因为var1是INT类型 ...
- Linux网络 - 数据包的接收过程【转】
转自:https://segmentfault.com/a/1190000008836467 本文将介绍在Linux系统中,数据包是如何一步一步从网卡传到进程手中的. 如果英文没有问题,强烈建议阅读后 ...
- Linux内核调试:kdump、vmcore、crash、kernel-debuginfo【转】
转自:https://blog.csdn.net/guowenyan001/article/details/19807555 一.简介 linux内核发送崩溃时,kdump会生成一个内核转储文件vmc ...
- zxing二维码
最近二维码用的很多,同时给了个zxing.dll和demo,用着还不错,就想着自己看看源码.于是搜索到一下资料: ZXing是一个开源Java类库用于解析多种格式的1D/2D条形码.目标是能够对QR编 ...
- python操作三大主流数据库(12)python操作redis的api框架redis-py简单使用
python操作三大主流数据库(12)python操作redis的api框架redis-py简单使用 redispy安装安装及简单使用:https://github.com/andymccurdy/r ...
- vmware不能装ghost系统怎么解决
一般情况下一台电脑最好只安装一个系统,因为多系统容易出现问题,所以很多用户都会在Vmware虚拟机上安装其他的系统,为了安装的方便,我们会选择ghost版的系统快速安装,但是有用户遇到vmware虚拟 ...
- javascript移动端禁止页面滑动的解决方案
1 前言 移动端网页,发现ios平台的iphone或者ipad,网页可以上下左右移动,而Android版则不会.仅作为记录使用. 2 代码 var mo=function(e){e.preventDe ...
- C语言-用函数实现社保工资查询系统
需求: 1.有登陆操作,超过三次需重新打开登录 2.查询五险一金.税前税后工资计算,个人与单位应缴明细 3.输入税后工资和税前工资都可查询 4.退出有询问确认操作 代码如下; #include< ...
- 彻底完全卸载 SQL Server 2005 的图文教程
彻底完全卸载 SQL Server 2005 的图文教程 SQL SERVER 2005不象SERVER 2000所有组件都汇总在一起,所以卸载时特别麻烦,如果不按正常的方法卸载,重新安装是不可能安装 ...
- Confluence 6 通过 SSL 或 HTTPS 运行 - 修改你 Confluence 的 server.xml 文件
下一步你需要配置 Confluence 来使用 HTTPS: 编辑 <install-directory>/conf/server.xml 文件. 取消注释下面的行: <Connec ...