【问题标题】:Systems programming: wait(&status)'s return value系统编程:wait(&status) 的返回值
【发布时间】:2016-01-19 05:55:36
【问题描述】:

在学习分叉和管道时,我偶然发现了以下优秀教程:https://www.cs.rutgers.edu/~pxk/416/notes/c-tutorials/pipe.html

但是,本教程将讨论如何在由最后一个父进程生成的 2 个子进程之间建立管道。虽然它在这方面做得很好,但某行代码让我困惑了一段时间:

while ((pid = wait(&status)) != -1) /* pick up all the dead children*/
    fprintf(stderr, "process %d exits with %d\n", pid, WEXITSTATUS(status));
exit(0);

我真的对wait(&status) 感到困惑(是的,我已经阅读了http://linux.die.net/man/2/wait 的手册页)。我们只是声明了一个int status,从来没有真正给它一个值,只是将它传递给等待。此状态是否在 wait() 函数中透明设置?

手册页说:

wait():成功时,返回终止子进程的进程ID;出错时返回-1。

所以在上面的代码行中,当wait(&status) 返回-1 时,while 循环退出。这很令人震惊:是否有错误,为什么?我们如何确保父母一直在旋转,直到所有孩子都正确终止?什么是“状态”,它是如何设置的?

编辑:补充一点,程序确实可以完美编译和运行。

【问题讨论】:

标签: c linux systems-programming waitpid


【解决方案1】:

当您致电wait(&status) 时,& 会说“获取地址”status

因此,您将 指针 传递给 status,而 不是 它的

wait 例程将使用此指针在返回之前用一个值填充status。这是除了函数的返回值。

因此,status 将在调用之后有效。

您不需要在调用之前将status 设置为任何内容 的原因是wait设置 一个值而没有 尝试预先使用该值。

status 包含一些内容。子程序是否正常退出(例如退出代码 0,或者错误代码为 [say] 1)。程序是否被信号终止(例如SIGSEGV)。孩子是否被“停止”[被stracegdb 和其他调试器使用]。如果您查看wait(2) 联机帮助页,有一大堆“帮助”宏,例如WIFEXITEDWEXITSTATUSWIFSIGNALEDWTERMSIG 等,可以帮助理解@ 987654341@值

对于返回值,-1 表示错误。但是,[在全局 errno] 中的错误可能是 ECHILD。这只是意味着没有更多的父进程的子进程剩余。 (即)程序已经等待并“收获”了之前通过fork 激发的所有孩子。

【讨论】:

  • 很公平! :) 您能否也请评论一下wait(&status)的返回值,更清楚一点,为什么当孩子终止时它似乎返回-1,为什么-1是错误值?
  • 为什么它似乎返回 -1”,如手册页所述,-1 可能表明没有孩子可以等待。 -1 用于指示错误,因为 PID 没有负值,wait 在“正常”情况下返回。 @nirvanaswap
  • @nirvanaswap:通常,wait() 返回死去孩子的 PID。当没有孩子要报告时,它返回-1。另请参阅waitpid(),以更精确地控制等待哪些进程。当我使用wait() 时,我的首选循环是int corpse; int status; while ((corpse = wait(&status)) != -1) printf("PID %d died with status 0x%.4X\n", corpse, status);,但使用pid 而不是corpse 也有意义。
  • 我建议在你的循环中检查 errno,例如:while (((corpse = wait(&status)) != -1) || (errno == EINTR)) … esp。如果您设置了任何信号处理程序。
猜你喜欢
  • 2016-07-30
  • 2014-07-30
  • 1970-01-01
  • 2021-05-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-11
  • 2022-11-24
相关资源
最近更新 更多