函数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 ...
随机推荐
- C++中的static关键字总结
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. 1.面向过程设计中的st ...
- 2017-2018-2 20165325 实验二《Java面向对象程序设计》实验报告
一.面向对象程序设计-1 1.检查点要求 参考 http://www.cnblogs.com/rocedu/p/6371315.html#SECUNITTEST 参考 http://www.cnblo ...
- Memcache的安装和使用【转】
转自:https://www.cnblogs.com/caoxiaojian/p/5715573.html Memcache是高性能,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问 ...
- Python运维开发基础03-语法基础 【转】
上节作业回顾(讲解+温习60分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen #只用变量和字符串+循环实现“用户登陆 ...
- 利用iscroll实现上拉加载下拉刷新
1.首先引用isScroll插件 说明:页面加载时初始化isScroll,然后调用pullDownAction()和pullUpAction(),每次切换tab时,只需要对pullDownAction ...
- boost--asio--读写大总结
NO.1 ASIO 读操作大总结: A. Boos::asio::read 同步读方式 void client::read_data(char * sourse , int num ) { bo ...
- unity实现剧情对话
using UnityEngine; using System.Collections; public class Test : MonoBehaviour { private string show ...
- webservice:com.sun.xml.internal.ws.server.ServerRtException: [failed to localize]
发布webservice发生了错误,一直没有能够解决,错误如下: Exception in thread "main" com.sun.xml.internal.ws.server ...
- oracle加密传输
参考文章: http://blog.itpub.net/24052272/viewspace-2129175/ oracle在传输过程中,正常是明文传输的,例如SQL以及执行的结果. 看看做的测试: ...
- Maven中央仓库地址整理
最近做项目的时候,一直发现常用的oschina maven源一直都没有反应,后面发现原来oschina竟然关闭了maven源服务,后面经同事推荐了阿里云的maven源,这速度杠杠的 Maven 中央仓 ...