waitpid函数:作用同wait,但可指定pid进程清理,可以不阻塞。

原型:pid_t waitpid(pid_t pid, int *status, in options);

返回值:成功时返回清理掉的子进程ID,失败返回-1;当第三个参数被设置为WNOHANG,且子进程还在运行时,返回0;

参数说明:

pid

> 0 回收指定ID的子进程  。

-1 回收任意子进程(相当于wait)

0 回收和当前调用waitpid一个组的所有子进程。

< -1 回收指定进程组内的任意子进程。

status

存储进程死亡的信息。

options

设置为阻塞或者不阻塞状态。

WNOHANG:不阻塞

0:阻塞

现在有一个题目:父进程fork 3 个子进程,三个子进程一个调用ps命令, 一个调用自定义程序1(正常),一个调用自定义程序2(会出段错误)。父进程使用waitpid对其子进程进行回收。

很简单,就是一些函数的调用。

代码:

#include
<cstdio>

#include
<unistd.h>

#include
<stdlib.h>

#include
<sys/types.h>

#include
<sys/wait.h>

 

int main()

{

    int i = 0;

    int status; //存储进程死亡信息

    pid_t pid; //存储wait函数返回值

 

    for (; i != 3; i++)

    {

        if (!fork())

        {

            break;

        }

    }

    if (i < 3)

    {

        if (0 == i)

        {

            int e_ret = execlp("ps", "ps", "aux", NULL);

            if (-1 == e_ret)

            {

                perror("execlp ps error ");

                exit(1);

            }

        }

        else
if (1 == i)

        {

            int e_ret = execl(" / home / lovedan / projects / test / a", "a", NULL);

            if (-1 == e_ret)

            {

                perror("execlp a error ");

                exit(1);

            }

        }

        else
if (2 == i)

        {

            int e_ret = execl(" / home / lovedan / projects / test / b", "b", NULL);

            if (-1 == e_ret)

            {

                perror("execlp b error ");

                exit(1);

            }

        }

    }

    else
if (i == 3)

    {

        //while (-1 != (pid = waitpid(-1, &status, WNOHANG)))//这里设置为不阻塞状态

        while (-1 != (pid = wait(&status))) //上面那句代码并没有问题。不阻塞的话,那输出真的是群魔乱舞。

        {

            if (0 == pid)

            {

                printf("The child process is running and does not recycle.\n");

            }

            else
if (pid > 0)

            {

                printf("The recovery sub - process is successful, and his ID is %d .\n", pid);

                if (WIFEXITED(status))

                {

                    printf("The subprocess exits normally, and the return value is %d .\n", WEXITSTATUS(status));

                }

                else
if (WIFSIGNALED(status))

                {

                    printf("The subprocess exits with an exception because it exits with a signal of %d .\n", WTERMSIG(status));

                }

            }

        }

        if (-1 == pid)

        {

            printf("No child processes can be recycled.\n");

        }

    }

    else

    {

        printf("i value error.i = %d", i);

        exit(1);

    }

 

    // printf("hello from fork_3_ps_normal_SegmentationFault!\n");

    return 0;

}

程序中的a和b是另外的两个小程序,根据题目意思来写的,很简单,代码就不拿上来了。

来看看不阻塞和阻塞状态下的输出:首先是不阻塞的;

The child process is running and does not recycle.

The child process is running and does not recycle.

The child process is running and does not recycle.

The child process is running and does not recycle.

I am a.

The recovery sub-process is successful, and his ID is 449 .

The subprocess exits with an exception because it exits with a signal of 11 .

The recovery sub-process is successful, and his ID is 448 .

The subprocess exits normally, and the return value is 216 .

The child process is running and does not recycle.

The child process is running and does not recycle.

The child process is running and does not recycle.

The child process is running and does not recycle.

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

The child process is running and does not recycle.

The child process is running and does not recycle.

root         1  0.0  0.0  10432   580 ?        Ss   08:29   0:00 /init

The child process is running and does not recycle.

The child process is running and does not recycle.

The child process is running and does not recycle.

The child process is running and does not recycle.

lovedan      2  0.0  0.0  25788  3704 tty1     Ss   08:29   0:00 -bash

The child process is running and does not recycle.

root        44  0.0  0.0  80408   912 ?        Ss   08:30   0:00 /usr/sbin/sshd

The child process is running and does not recycle.

lovedan    446  0.0  0.0  36172   516 tty1     S    09:06   0:00 ./fork_3_ps_normal_SegmentatThe child process is running and does not recycle.

lovedan    447  0.0  0.0  51704  1832 tty1     R    09:06   0:00 ps aux

The child process is running and does not recycle.

The recovery sub-process is successful, and his ID is 447 .

The subprocess exits normally, and the return value is 0 .

No child processes can be recycled.

完全是群魔乱舞。

来看看阻塞状态下的:

I am a.

The recovery sub-process is successful, and his ID is 727 .

The subprocess exits normally, and the return value is 216 .

The recovery sub-process is successful, and his ID is 728 .

The subprocess exits with an exception because it exits with a signal of 11 .

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

root         1  0.0  0.0  10432   580 ?        Ss   08:29   0:00 /init

lovedan      2  0.0  0.0  25788  3708 tty1     Ss   08:29   0:00 -bash

root        44  0.0  0.0  80408   912 ?        Ss   08:30   0:00 /usr/sbin/sshd

lovedan    725  0.0  0.0  36172   512 tty1     S    09:10   0:00 ./fork_3_ps_normal_SegmentationFault.out

lovedan    726  0.0  0.0  51704  1832 tty1     R    09:10   0:00 ps aux

The recovery sub-process is successful, and his ID is 726 .

The subprocess exits normally, and the return value is 0 .

No child processes can be recycled.

这就比较好了。满足。

用waitpid函数回收进程的更多相关文章

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

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

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

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

  3. linux多进/线程编程(3)——wait、waitpid函数和孤儿、僵尸进程

    当使用fork创建多个进程后,需要解决子进程回收的问题.wait和waitpid函数就是做这个工作的. 假设子进程没有合理的回收,可能会带来两个问题: 1.孤儿进程(父进程挂了,子进程活着),孤儿进程 ...

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

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

  5. 回收进程用户空间资源 exit()函数 _exit()函数 atexit()函数 on_exit()函数

    摘要:本文主要讲述进程的终止方式,以及怎样使用exit()函数来终止进程.回收进程用户空间资源:分析了exit()函数与_exit()函数,returnkeyword的差异.同一时候具体解读了怎样使用 ...

  6. UNIX环境编程学习笔记(21)——进程管理之获取进程终止状态的 wait 和 waitpid 函数

    lienhua342014-10-12 当一个进程正常或者异常终止时,内核就向其父进程发送 SIGCHLD信号.父进程可以选择忽略该信号,或者提供一个该信号发生时即被调用的函数(信号处理程序).对于这 ...

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

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

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

    僵尸进程:子进程终止了,但是父进程没有回收子进程的资源PCB.使其成为僵尸进程 孤儿进程:父进程先与子进程结束了,使得子进程失去了父进程,这个时候子进程会被1号进程init进程领养,成为孤儿进程 为了 ...

  9. waitpid()函数

    waitpid函数 作用同于wait,但可指定pid进程清理,可以不阻塞. pid_t waitpid(pid_t pid,int *status,int options);成功:返回清理掉的子进程I ...

随机推荐

  1. [UE4]更通用的接口,将UserWidget作为图标添加到小地图

    将图标改成UserWidget添加到小地图,UserWidget支持动画特效,更丰富小地图的功能. 一.在小地图图标结构体中,将Flag数据类型改成UserWidget,删除ImageWidget(类 ...

  2. [UE4]关于分支Sequence和条件分支的组合用法

    当需要不管条件语句是否成立的后面都需要执行的语句,可以使用“Sequence”来分支,达到简化蓝图连线的目的.如下图所示:

  3. CNN卷积层基础:特征提取+卷积核+反向传播

    本篇介绍卷积层的线性部分 一.与全连接层相比卷积层有什么优势? 卷积层可以节省参数,因为卷积运算利用了图像的局部相关性——分析出一小片区域的特点,加上Pooling层(汇集.汇聚),从附近的卷积结果中 ...

  4. Hbase访问方式

    Hbase访问方式 Hbase shell命令操作 Hbase shell命令操作--general操作 首先启动Hbase 启动shell 查看表结构 删除一个表 创建表和查看表结构 插入几条数据 ...

  5. Javascript的闭包及其使用技巧实例

    Javascript的闭包及其使用技巧实例 一.闭包的基本概念 闭包(Closure)是一个引用了自由变量的函数,记录了该函数在定义时的scope chain.又称词法闭包(Lexical Closu ...

  6. 安装MySQL半同步复制

    一.简介 从MySQL5.5开始,MySQL以插件的形式支持半同步复制.如何理解半同步呢?首先我们来看看异步,全同步的概念 异步复制(Asynchronous replication) MySQL默认 ...

  7. 《马哥出品高薪linux运维教程》wingkeung学习笔记-linux基础入门课程

    计算机原理概念: 1.CPU和内存中的存储单元通信线路称为总线(BUS),总线是被指令和数据复用的,所以也称为前端总线. 2.计算机中计算频率的时间标准即晶体振荡器原理,精确计算时间长度,根据相同的时 ...

  8. 3-scala高级

    1.模式匹配 //①简单表示: sign = ch match { case '+' => 1 case '-' => -1 case '_' => 0 } //②守卫:(case中 ...

  9. JVM总结-虚拟机怎么执行字节码

    1. JRE,JDK JRE : 包含运行 Java 程序的必需组件,Java 虚拟机+ Java 核心类库等. JDK :  JRE + 一系列开发.诊断工具. 2. java字节码 编译器将 Ja ...

  10. linux中的IP地址的修改

    一,图形界面,setup 二,修改文件 1,修改主机名字 vi /etc/sysconfig/network NETWORKING=yes #HOSTNAME=localhost.localdomai ...