函数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 ...
随机推荐
- 【Shell】30分钟关闭Tcpdump,开启Tcpdump、检测目录大小终止任务
场景 按照一定时间规律运行Tcpdump 思路 编程思路细化思考 查看文件个数 file_count_results=`ls -al "C:\\Users\\Windows32\\Deskt ...
- 看完此文还不懂NB-IoT,你就过来掐死我吧...
看完此文还不懂NB-IoT,你就过来掐死我吧....... 1 1G-2G-3G-4G-5G 不解释,看图,看看NB-IoT在哪里? 2 NB-IoT标准化历程 3GPP NB-IoT的标准化始于20 ...
- Flash硬件原理
1.2.1. 什么是Flash Flash全名叫做Flash Memory,从名字就能看出,是种数据存储设备,存储设备有很多类,Flash属于非易失性存储设备(Non-volatile Memory ...
- Maven多模块项目加载
Maven多模块项目中如何让Spring运行时成功加载指定的子模块 将子模块pom加入到父模块pom的定义中,并继承父模块 在web.xml中配置加载子模块的Spring配置文件 在启 ...
- elasticsearch索引自动清理
一 es 基本操作 查看所有的索引文件: curl -XGET http://localhost:9200/_cat/indices?v GET /_cat/indices?v DELETE /fi ...
- cocos2d内存管理,类的生命周期
下面资料来自<Cocos2d-x之Lua核心编程>
- boolalpha的作用
#include <iostream>using namespace std;int main(){ bool b=true; cout << &q ...
- Oracle 行转列pivot 、列转行unpivot 的Sql语句总结
这个比较简单,用||或concat函数可以实现 select concat(id,username) str from app_user select id||username str from ap ...
- Confluence 6 重新获得附件指南
每一个文件在恢复上传到 Confluence 的时候必须单独重命名,你可以通过下面说明的 3 个方法中选择一个进行操作: 选择 A - 通过文件名恢复附件 如果你知道你需要恢复的每一个文件名,尤其是你 ...
- 爬虫框架之Scrapy
一.介绍 二.安装 三.命令行工具 四.项目结构以及爬虫应用简介 五.Spiders 六.Selectors 七.Items 八.Item Pipelin 九. Dowloader Middeware ...