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. Python 进阶——如何正确使用 yield?

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 在 Python 开发中, yield 关键字的使用其实较为频繁,例如大集合的生成,简化代码结构.协 ...

  2. C#未能找到类型或命名空间名称xxxxxx的可能原因

    常见原因 原因:使用的.NET版本不一样 今天又被这问题撞上了,结果神奇般的解决了 谷歌了很久都没有找到真正有用的解决方案,所以在这儿写下,让更多的人看到 最根本的原因其实就是引用的问题,引用错了,然 ...

  3. 简单谈谈contextlib的使用

    简单谈谈contextlib的使用 写在前面 做这件事的原因: 在看书的时候,我发现了有大佬们用contextlib管理上下文,真的很牛皮,但是百度了以下,每个大佬都写了很多很全很深刻,讲道理五花八门 ...

  4. 在vue cli3.0 里面下载less,下载成功了还是提示没有 需要下载

    今天正好新建了一个项目,在用less的时候就各种花样报错提示我: Failed to resolve loader: less-loaderYou may need to install it.Err ...

  5. JAVA递归算法及经典递归例子 对于这个汉诺塔问题

    前言:递归(recursion):递归满足2个条件 1)有反复执行的过程(调用自身) 2)有跳出反复执行过程的条件(递归出口) 第一题:汉诺塔 对于这个汉诺塔问题,在写递归时,我们只需要确定两个条件: ...

  6. 【Redis】内部数据结构自顶向下梳理

    本博客将顺着自顶向下的思路梳理一下Redis的数据结构体系,从数据库到对象体系,再到底层数据结构.我将基于我的一个项目的代码来进行介绍:daredis.该项目中,使用Java实现了Redis中所有的数 ...

  7. js实现页面消息滚动效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. lua脚本简介

    Lua [1]  是一个小巧的脚本语言.它是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个由Roberto Ier ...

  9. 远程控制卡 使用ipmitools设置ipmi

    远程控制卡 使用ipmitools设置ipmi 使用DELL的远程控制卡可以方便的管理服务器 在CentOS中可以使用ipmitools管理 IPMI( Intelligent Platform Ma ...

  10. TurtleBot3 Waffle (tx2版华夫)(5)激活你的雷达

    重要提示:请在配网通信成功后进行操作,配网后再次开机需要重新验证通信: 重要提示:[Remote PC]代表PC端.[TurtelBot]代表树莓派端: 5.1.操作步骤 1)[Remote PC]  ...