c - 等待 C 中的进程

标签 c unix fork wait zombie-process

我一直在阅读有关 wait()waitpid() 的文档,但我仍然对它们的工作方式有些困惑(我收集了 wait(&status) 等同于 waitpid(-1, &status, 0);。下面是我正在处理的一些小代码片段。请帮助我了解这些片段是否编写正确,如果不正确,那是为什么。

目标 1:收割所有僵尸 child 。

int reapedPid;
do {
    reapedPid = waitpid(-1,NULL,WNOHANG);
} while (reapedPid > 0);

我在这里尝试做的是遍历所有子节点,如果完成则收割子节点,如果没有完成则让它继续运行,当我用完子节点时 reapedPid == -1 并且循环退出。我在这里感到困惑的原因是我看不到 waitpid() 应该如何知道哪些 child 已经被检查过,哪些没有。它做任何这样的检查吗?还是这种方法行不通?

目标 2:等待所有 child 完成。

int pid;
do {
    pid = wait(NULL);
} while (pid != -1);

在这里,我不关心子进程的结果状态是什么——这应该一直等待每个子进程完成,无论是成功还是失败,然后退出。我认为这段代码是正确的,但我不确定。

目标 3:fork 一个子进程并等待它完成。

int pid = fork();
if (pid < 0) {
    // handle error.
}
else if (pid == 0) {
    // execute child command
}
else {
    int status;
    int waitedForPid = waitpid(pid,&status,0);
    assert(waitedForPid == pid);
}

在这里,我只是尝试 fork 进程并让父进程等待子进程完成。我不完全确定我是否应该在此处传递 0 选项,但似乎 WNOHANG、WUNTRACED 和 WCONTINUED 与我的目标并不真正相关。

最佳答案

  1. 跟踪进程是内核的工作。跟踪死进程是微不足道的。内核可以判断哪些子进程已死亡但尚未等待,并会在每次调用时返回其中一个已死亡的子进程,直到没有剩余可报告为止。 (由于 WNOHANG 选项,可能还有 child 要等待,但剩下的 child 还没有死。)

  2. 第二个循环也很好,几乎等同于第一个。不同之处在于它会挂起等待所有 child 都死了再返回 -1。

  3. 第三个片段很好;除非在特殊情况下(例如程序中的另一个线程也在等待 child 并收集尸体),否则断言将为真。但是,如果您在某个地方启动了另一个进程并让它在后台运行,您可能正在收集僵尸,而通过修改其他循环,您可以收集僵尸并仍然等待正确的 child :

    int pid = fork();
    
    if (pid < 0)
    {
        // handle error.
    }
    else if (pid == 0)
    {
        // execute child command
    }
    else
    {
        int status;
        int corpse;
        while ((corpse = waitpid(-1, &status, 0)) > 0)
            if (corpse == pid)
                break;
    }
    

关于c - 等待 C 中的进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20062504/

相关文章:

c - Y86 求和程序困惑

C 多维数组 : Am I missing something?

linux - 如何根据 AWK/UNIX 中的公共(public)字段将行中分离的字段合并为一个

c - 如何在 C 中将字符串解析为日期时间结构?

c - 当在另一个文件中声明结构时,如何使用结构作为函数的参数?

regex - 正则表达式$$是什么意思?

linux - 在 shell 脚本中将全局变量从子级导出到父级

c - 如何获取子进程的退出状态?

c - 如何知道给 exec 的命令是否存在?

ruby - 如何锁定 ruby 中fork共享的IO