系统如何知道没有更多的孩子可以接受

时间:2011-07-19 19:16:49

标签: c linux multiprocessing ubuntu-10.04

基于此:http://man7.org/tlpi/code/online/book/procexec/multi_wait.c.html

int
main(int argc, char *argv[])
{
    int numDead;       /* Number of children so far waited for */
    pid_t childPid;    /* PID of waited for child */
    int j;

    if (argc < 2 || strcmp(argv[1], "--help") == 0)
        usageErr("%s sleep-time...\n", argv[0]);

    setbuf(stdout, NULL);           /* Disable buffering of stdout */

    for (j = 1; j < argc; j++) {    /* Create one child for each argument */
        switch (fork()) {
        case -1:
            errExit("fork");

        case 0:                     /* Child sleeps for a while then exits */
            printf("[%s] child %d started with PID %ld, sleeping %s "
                    "seconds\n", currTime("%T"), j, (long) getpid(),
                    argv[j]);
            sleep(getInt(argv[j], GN_NONNEG, "sleep-time"));
            _exit(EXIT_SUCCESS);

        default:                    /* Parent just continues around loop */
            break;
        }
    }

    numDead = 0;
    for (;;) {                      /* Parent waits for each child to exit */
        childPid = wait(NULL);
        if (childPid == -1) {
            if (errno == ECHILD) {
                printf("No more children - bye!\n");
                exit(EXIT_SUCCESS);
            } else {                /* Some other (unexpected) error */
                errExit("wait");
            }
        }

        numDead++;
        printf("[%s] wait() returned child PID %ld (numDead=%d)\n",
                currTime("%T"), (long) childPid, numDead);
    }
}
  

出错时,wait返回-1。一个可能的错误是调用   过程没有(以前未被等待的)孩子,由表示   错误值 ECHILD

$ ./multi_wait 7 1 4
[13:41:00] child 1 started with PID 21835, sleeping 7 seconds
[13:41:00] child 2 started with PID 21836, sleeping 1 seconds
[13:41:00] child 3 started with PID 21837, sleeping 4 seconds
[13:41:01] wait() returned child PID 21836 (numDead=1)
[13:41:04] wait() returned child PID 21837 (numDead=2)
[13:41:07] wait() returned child PID 21835 (numDead=3)
No more children - bye!

问题

系统如何知道没有更多的孩子无法接受并返回ECHILD。 例如,在这个例子中,如果有些孩子睡了很长时间怎么办?

2 个答案:

答案 0 :(得分:2)

系统会跟踪每个流程。您可以使用命令ps xf查看Ubuntu系统上的进程树。

特别是,在此列表中,您可以看到每个进程的状态:R =正在运行,S =正在休眠,T =已停止,Z =僵尸(已终止,等待父级使用wait()系统收集退出状态呼叫)。

使用此信息,系统知道何时返回ECHILD(不再有孩子)。

答案 1 :(得分:1)

内核为每个正在运行的进程维护一个数据结构。它还维护死亡但未被等待的进程(僵尸)的数据结构。父进程的数据结构有关于它还没有等待的孩子的信息(无论是僵尸还是还活着,僵尸的主要区别在于它们几乎没有肉体,即它们的数据结构只包含退出状态,资源使用,而不是更多,所以他们是非常重量级的。)