函数wait

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

1. 函数wait:一次只能回收一个子进程

pid_t wait(int *status);   status传出参数

进程终止时,操作系统隐式回收机制会:1. 关闭所有的文件描述符 2. 释放用户空间分配的内存。内核PCB仍存在,其中保存该进程的退出状态。(正常终止--------退出值;异常终止-------终止信号)

可使用wait函数传出参数status来保存进程的退出状态,借助宏函数来进一步判断进程终止的具体原因,宏函数可分为三组:

  1. WIFEXITED(status):为非0,进程正常结束;WEXITSTATUS(status) :如上宏为真,使用此宏  获取进程退出状态(exit的参数)
  2. WIFSIGNALED(status):为非0,进程异常终止;WTERMSIG(status):如上宏为真,使用此宏  获取进程终止的那个信号编号
  3. 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的更多相关文章

  1. 阻塞进程函数 wait()和waitpid()

    1.  wait()和waitpid()函数说明 wait() 进程一旦调用了wait(), 就立即阻塞自己,由wait自动分析是否有当前进程的某个子进程已经退出,如果让它找到了一个已经变成僵尸的子进 ...

  2. wait/waitpid函数与僵尸进程、fork 2 times

    一.僵尸进程 当子进程退出的时候,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) 子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程, ...

  3. 【Linux】僵尸进程,孤儿进程以及wait函数,waitpid函数(有样例,分析很详细)

    本文内容: 1.僵尸进程,孤儿进程的定义,区别,产生原因,处理方法 2.wait函数,waitpid函数的分析,以及比较 背景:由于子进程的结束和父进程的运行是一个异步的过程,即父进程永远无法预测子进 ...

  4. wait函数与waitpid函数(僵尸进程)

    当子进程退出时,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) 子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程.它只保留最小的一些 ...

  5. 父进程等待子进程结束 waitpid wait

    我们一直在强调一个概念就是进程是一个程序执行的实例,是内核在虚拟概念下创建的实体,它实例化的体现在用户态就是程序代码和代码使用的变量(存储空间),在内核态就是内核为我们每个进程所保存的数据结构(状态信 ...

  6. 对于linux下system()函数的深度理解(整理)

    原谅: http://blog.sina.com.cn/s/blog_8043547601017qk0.html 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同 ...

  7. 【转】linux中waitpid及wait的用法

    原文网址:http://www.2cto.com/os/201203/124851.html wait(等待子进程中断或结束) 表头文件      #include<sys/types.h> ...

  8. system函数的总结

    最近在看APUE第10章中关于system函数的POSIX.1的实现.关于POSIX.1要求system函数忽略SIGINT和SIGQUIT,并且阻塞信号SIGCHLD的论述,理解得不是很透彻,本文就 ...

  9. linux中waitpid及wait的用法

    wait(等待子进程中断或结束) 表头文件      #include<sys/types.h>      #include<sys/wait.h> 定义函数 pid_t wa ...

随机推荐

  1. 【转】MySQL— pymysql and SQLAlchemy

    [转]MySQL— pymysql and SQLAlchemy 目录 一.pymysql 二.SQLAlchemy 一.pymysql pymsql是Python中操作MySQL的模块,其使用方法和 ...

  2. 1.Linux电源管理-休眠与唤醒【转】

    转自:https://www.cnblogs.com/lifexy/p/9629699.html 1.休眠方式 在内核中,休眠方式有很多种,可以通过下面命令查看 # cat /sys/power/st ...

  3. MySQL5.7 锁定用户【转】

    使用ALTER USER 语句锁定 mysql>ALTER USER 'demo'@'localhost' ACCOUNT LOCK; Query OK, rows affected (0.00 ...

  4. 更新ocr voting后第二个节点启动不起来

    [+ASM2]@qdcx-db2[/home/grid]$crsctl check crs CRS-4638: Oracle High Availability Services is online ...

  5. HDU 4455

    题意 : 题目 给你一个序列 , 查询 t ,问  序列 连续 长度为 t 的子区间 的不同数 的和 巧妙的动态规划 数据大, Dp可以 O(n) #include<iostream> # ...

  6. 【原创】Linux基础之测试域名IP端口连通性

    一 测试域名是否可达 1 ping # ping www.baidu.comPING www.a.shifen.com (220.181.112.244) 56(84) bytes of data.6 ...

  7. Webapi 跨域 解决解决错误No 'Access-Control-Allow-Origin' header is present on the requested resource 问题

    首先是web端(http://localhost:53784) 请求 api(http://localhost:81/api/)时出现错误信息: 查看控制台会发现错误:XMLHttpRequest c ...

  8. mtu简单说明

    总结:本地的mtu值==网络设备的mtu值是最优的,一般本地和网络设备的默认值都是1500(字节),没什么特殊需求,尽量不要修改 一.什么是 MTU 值   1 从字面上来说,MTU 是英文 Maxi ...

  9. 【进阶3-2期】JavaScript深入之重新认识箭头函数的this(转)

    这是我在公众号(高级前端进阶)看到的文章,现在做笔记 https://github.com/yygmind/blog/issues/21 上篇文章详细的分析了各种this的情况,看过之后对this的概 ...

  10. 使用 Apache 来限制访问 Confluence 6 的管理员界面

    限制特定的 IP 地址可以访问管理员后台 Confluence 的管理员控制台界面对整个应用来说是非常重要的,任何人访问 Confluence 的控制台不仅仅可以访问 Confluence 安装实例, ...