1. 函数介绍

  wait函数:调用该函数使进程阻塞,直到任意一个子进程结束,或者该进程接收到了一个信号为止,如果该进程没有子进程或该进程的子进程已经结束,wait函数立即返回。

  waitpid函数:与wait函数类似,但可以指定子进程的PID以及等待方式(阻塞和非阻塞)。

  他们的函数原型如下:

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

函数参数:

  status是一个int型的指针,表示程序退出时的状态,如果传入NULL则表示不关心程序退出时的状态。

  传入的pid的值有好几种不同的情况:

    pid > 0:要等待退出的子进程PID;

    pid = -1:等待任意一个子进程退出;

    pid = 0:等待其组ID等于调用进程的组ID的任意子进程;

    pid < -1:等待其组ID等于pid的绝对值的任意子进程。

  options:

    WNOHANG:若由pid指定的子进程并不立即可用,则waitpid不阻塞,此时返回值为0。

    WUNTRACED:若某实现支持作业控制,则有pid指定的任一子进程状态已暂停,且其状态自暂停以来还没报告过,则返回其状态。(该选项不常用)。

    0:同wait,阻塞父进程,等待子进程退出。

    其中WNOHANG和WUNTRACED可以通过 “|” 运算符连接。

  实际上wait就是封装后的waitpid:

static inline pid_t wait(int * wait_stat)
{
return waitpid(-1, wait_stat, 0);
}

返回值:

  正常:结束的子进程的ID号,使用选项WNOHANG而没有子进程结束时返回0,调用出错返回-1。

2. 测试用例

  测试代码:

 1 #include <stdio.h>
2 #include <unistd.h>
3 #include <sys/wait.h>
4
5 int main(int argc, const char *argv[])
6 {
7 int pid;
8 int wait_ret = 0;
9
10 pid = fork();
11
12 if(pid == 0) { /* 子进程 */
13 printf("#############\n");
14 printf("I'm child\n\n");
15 printf("My PID = %d\n", getpid());
16 sleep(2);
17 printf("I'm dead\n");
18 } else if (pid > 0) { /* 父进程 */
19 printf("#############\n");
20 printf("I'm parent\n");
21 printf("wait...\n");
22 wait_ret = wait(NULL);
23 printf("wait_ret = %d\n", wait_ret);
24 }
25
26 return 0;
27 }

  测试结果:

  从测试结果可以看出,wait函数阻塞了,等子进程结束之后才继续,并且得到的返回值正是子进程的PID。

  接下来换waitpid的测试程序:

 1 #include <stdio.h>
2 #include <unistd.h>
3 #include <sys/wait.h>
4
5 int main(int argc, const char *argv[])
6 {
7 int pid;
8 int wait_ret = 0;
9
10 pid = fork();
11
12 if (pid == 0) { /* 子进程 */
13 printf("#############\n");
14 printf("I'm child\n\n");
15 printf("My PID = %d\n", getpid());
16 sleep(3);
17 printf("I'm dead\n");
18 } else if (pid > 0) { /* 父进程 */
19 printf("#############\n");
20 printf("I'm parent\n");
21 while (1) {
22 wait_ret = waitpid(pid, NULL, WNOHANG);
23 printf("wait_ret = %d\n", wait_ret);
24 sleep(1);
25 if (wait_ret != 0) {
26 printf("Child dead\n");
27 break;
28 }
29 }
30 }
31
32 return 0;
33 }

  测试结果:

  从结果可以看出,由于传入了WNOHANG,因此waitpid函数不阻塞,在子进程没有退出的时候waitpid返回0,在子进程退出之后waitpid返回的是子进程的PID。

3、wait和waitpid的更多相关文章

  1. Linux 等待进程结束 wait() 和 waitpid()

    若子进程先于父进程结束时,父进程调用wait()函数和不调用wait()函数会产生两种不同的结果: --> 如果父进程没有调用wait()和waitpid()函数,子进程就会进入僵死状态. -- ...

  2. linux下使用fork,exec,waitpid模拟system函数

    代码如下: #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include &l ...

  3. 详解wait和waitpid函数

    #include <sys/types.h> /* 提供类型pid_t的定义 */ #include <sys/wait.h> pid_t wait(int *status) ...

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

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

  5. 系统调用wait、waitpid和exec函数

    本文介绍了Linux下的进程的一些概念,并着重讲解了与Linux进程管理相关的重要系统调用wait,waitpid和exec函数族,辅助一些例程说明了它们的特点和使用方法. 1.7 背景 在前面的文章 ...

  6. linux c学习笔记----进程创建(fork,wait,waitpid)

    1.pid_t fork(); (1)当一个进程调用了fork 以后,系统会创建一个子进程.这个子进程和父进程不同的地方只有他的进程ID 和父进程ID,其他的都是一样.就象符进程克隆(clone)自己 ...

  7. 对while((pid = waitpid(-1, &stat, WNOHANG)) > 0)不懂的地方,现在懂了

    while((pid = waitpid(-1, &stat, WNOHANG)) > 0) 需要写到信号处理函数中,假如有10个子进程 只要父进程能够收到最后一个信号,就能把前面丢失的 ...

  8. wait、waitpid 僵尸进程 孤儿进程

    man wait: NAME wait, waitpid, waitid - wait for process to change state SYNOPSIS #include <sys/ty ...

  9. 进程控制之wait和waitpid函数

    当一个进程正常或异常终止时,内核就向其父进程发送SIGCHLD信号.因为子进程终止是个异步事件(这可以在父进程运行的任何时候发生),所以这种信号也是内核向父进程发的异步通知.父进程可以选择忽略该信号, ...

  10. 【转】linux : waitpid函数

    原文网址:http://blog.csdn.net/jifengszf/article/details/3067841 [waitpid系统调用]       功能描述: 等待进程改变其状态.所有下面 ...

随机推荐

  1. 嵌入式开发笔记——调试组件SEGGER_HardFaultHandle

    一.前言 在使用Cortex-M内核的MCU进行开发时,有时候会因为对内存错误访问等原因造成程序产生异常从而进入HardFaultHandler错误中断.如果程序结构比较复杂,尤其是运行了RTOS时可 ...

  2. java基础:进制详细介绍,进制快速转换,二维数组详解,循环嵌套应用,杨辉三角实现正倒直角正倒等腰三角,附练习案列

    1.Debug模式 1.1 什么是Debug模式 是供程序员使用的程序调试工具,它可以用于查看程序的执行流程,也可以用于追踪程序执行过程来调试程序. 1.2 Debug介绍与操作流程 如何加断点 选择 ...

  3. 为什么会有kafka消息系统?小问题藏着大细节!

    前言:老刘今天写这篇文章首先想对一些复制粘贴的博客表达不满:其次是想用通俗易懂的话解释消息系统:最后欢迎各位英雄好汉.女中豪杰前来battle. 1. 为什么有消息系统? 1.1 背景 今天复习kaf ...

  4. CentOS7 实战源码安装mysql5.7.17数据库服务器

    CentOS7 实战源码安装mysql5.7.17数据库服务器 简介:实战演练mysql数据库服务器的搭建  mysql简介: mysql是一个开源的关系型数据库管理系统,现在是oracle公司旗下的 ...

  5. phaser3入门教程-从零开始开发一个打砖块游戏

    项目代码 项目代码 体验一下 空格开始,左右箭头控制移动 体验一下 Phaser简介 Phaser是一个HTML5游戏框架.它使用了许多HTML5 API,例如Canvas,WebGL,Audio,G ...

  6. 常见数据库的JDBC URL

    转自:http://blog.csdn.net/ring0hx/article/details/6152528 Microsoft SQL Server Microsoft SQL Server JD ...

  7. Python将GIF图片转换成png图片帧

    效果图: 转换之后保存到文件夹中: 代码如下:(第三方库pillow,安装方法:在cmd中输入:  pip install pillow) from PIL import Image import o ...

  8. JavaDailyReports10_04

    修改后的出题系统 1.添加用户自定义是否出现乘除法,自由选择符号和个数,并且可以自定义操作数的取值范围. 1 /* 2 * 2.可定制(数量/打印方式):输入大的数量值,测试一下系统是否崩溃,反向查找 ...

  9. pixi.js 图像资源(svg)转纹理

    当Pixi使用WebGL去调用GPU渲染图像时,需要先将图像转化为GPU可以处理的版本.而能够被GPU处理的图像就叫做纹理,在pixi中使用纹理缓存来存储和引用所有纹理.通过将纹理分配给精灵,再将精灵 ...

  10. LAMP搭建 转

    LAMP搭建 LAMP环境配置安装注意安装步骤及说明事项. (一)           安装gcc gcc glibc-devel glibc-headers kernel-headers libgo ...