系统如何知道不再有未等待的孩子

发布于 2024-11-25 11:47:55 字数 2342 浏览 5 评论 0原文

基于此: 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。一种可能的错误是调用 进程没有(之前未等待的)子进程,这由 errno 值 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。 例如,在这个例子中,如果有些孩子睡很长时间怎么办?

Based on this: 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);
    }
}

On error, wait returns -1. One possible error is that the calling
process has no (previous unwaited-for) children, which is indicated by
the errno value 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!

Question

How does the system know there is no more unwaited-for children and return ECHILD.
For example, in this example, what if some children sleep for very long time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白首有我共你 2024-12-02 11:47:55

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

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

使用此信息,系统知道何时返回 ECHILD(没有更多的孩子留下)。

The system keeps track of every process. You may use the command ps xf to see the process tree on your Ubuntu system.

In particular, in this list you can see the state of each process: R = running, S = sleeping, T = stopped, Z = zombie (terminated, waiting for parent to collect exit status with wait() system call).

Using this information, the system knows when to return ECHILD (no more children left).

哎呦我呸! 2024-12-02 11:47:55

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

The kernel maintains a data structure for each running process. It also maintains data structures for dead but unwaited-for processes (zombies). The parent process's data structure has information on the children it hasn't waited for yet (whether thay are zombies or are still alive, the main difference of zombies is that they have almost no flesh, i.e. their data structures only contain the exit status, resource usage, and not much more, so they are very loghtweight).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文