操作系统 - 程序不会按照特定的顺序回收子进程

来源:互联网 发布:使知意思 编辑:程序博客网 时间:2024/04/30 15:42

eg1:

// waitpid1.c// 2015-08-26    Lucifer Zhang// Using the waitpid function to reap zombie children in no// particular order.#include "csapp.h"#define N 2int main() {    int status, i;    pid_t pid;    /* Parent creates N children */    for (i = 0; i < N; i++)                       //line:ecf:waitpid1:forif ((pid = Fork()) == 0)  /* child */     //line:ecf:waitpid1:fork    exit(100+i);                          //line:ecf:waitpid1:exit    /* Parent reaps N children in no particular order */    while ((pid = waitpid(-1, &status, 0)) > 0) { //line:ecf:waitpid1:waitpidif (WIFEXITED(status))                    //line:ecf:waitpid1:wifexited    printf("child %d terminated normally with exit status=%d\n",   pid, WEXITSTATUS(status));     //line:ecf:waitpid1:wexitstatuselse    printf("child %d terminated abnormally\n", pid);    }    /* The only normal termination is if there are no more children */    if (errno != ECHILD)                          //line:ecf:waitpid1:errnounix_error("waitpid error");    exit(0);}
        第15行,父进程创建N个子进程,在第16行,每个子进程以一个唯一的退出状态退出。在第19行,父进程用waitpid作为while循环的测试条件,等待它所有的子进程终止,因为第一个参数是-1,所以对waitpid的调用会阻塞,知道任意一个子进程终止。在每个子进程终止时,对waitpid的调用会返回,返回值为该子进程的非零PID。第20行检查子进程的退出状态。如果子进程是正常终止的,在此是以调用exit函数终止的,那么父进程就提取出退出状态,把它输出到stdout上。

        当回收了所有的子进程之后,再调用waitpid就返回-1,并且设置errno为ECHILD。第28行检查waitpid函数是正常终止的,否则就输出一个错误消息。

        测试:


        注意,程序不会按照特定的顺序回收子进程。子进程回收的顺序是这台特定的计算机的属性。在另一个系统上,甚至在同一个系统上再次执行一次,两个子进程都可能以相反的顺序被回收。上面的测试结果也说明了这一点。这是非确定性的(nondeterministic)行为的一个示例,这种非确定性行为使得对并发进行推理非常困难。

    下面这个例子做了简单的改变,消除了不确定性,按照父进程创建子进程的相同顺序来回收这些子进程。


eg2:

// waitpid1.c// 2015-08-26    Lucifer Zhang// Using waitpid to reap zombie children in the order they were created.#include "csapp.h"#define N 2int main() {    int status, i;    pid_t pid;    /* Parent creates N children */    for (i = 0; i < N; i++)                       //line:ecf:waitpid1:forif ((pid = Fork()) == 0)  /* child */     //line:ecf:waitpid1:fork    exit(100+i);                          //line:ecf:waitpid1:exit    /* Parent reaps N children in no particular order */    while ((pid = waitpid(-1, &status, 0)) > 0) { //line:ecf:waitpid1:waitpidif (WIFEXITED(status))                    //line:ecf:waitpid1:wifexited    printf("child %d terminated normally with exit status=%d\n",   pid, WEXITSTATUS(status));     //line:ecf:waitpid1:wexitstatuselse    printf("child %d terminated abnormally\n", pid);    }    /* The only normal termination is if there are no more children */    if (errno != ECHILD)                          //line:ecf:waitpid1:errnounix_error("waitpid error");    exit(0);}

0 0
原创粉丝点击