【问题标题】:C - Under what conditions will a call to waitpid() return -1, signalling an error?C - 在什么情况下调用 waitpid() 返回 -1,表示错误?
【发布时间】:2014-07-05 12:46:58
【问题描述】:

我正在编写一个 SIGCHLD 处理程序,我想知道在什么情况下调用 waitpid() 会返回 -1?

更具体地说,如果我创建一个循环,在其中调用 waitpid(...) 并希望它运行直到所有已终止的子进程都被回收,我是否会迭代直到 waitpid(...) 返回 -1?否则,我怎么知道还有没有孩子需要收割呢?

【问题讨论】:

  • 一个信号可能会中断等待...
  • 您是否尝试过阅读手册页?它解释了返回-1的原因。
  • 我查看了手册页。要么我不理解其中的描述,要么 waitpid() 返回 -1 可能不是我所描述的循环所必需的,它具有收获所有终止子进程的效果。无论哪种情况,我都在寻找答案。
  • 处理 sigchld 不是一个好习惯。它与任何产生子进程的库代码(包括 popen)都危险地不兼容。相反,您应该只从创建它们的逻辑模块中为您知道的孩子 waitpid。

标签: c process handler waitpid sigchld


【解决方案1】:

waitpid() 在这些情况下可以返回-1

  1. 该进程没有尚未等待的子进程。在这种情况下,errno 设置为 ECHILD。如果您正在循环获取进程组中的所有子进程或所有子进程(即,您将 pid 设置为 -10),那么当这种情况发生时,您应该跳出循环。如果 SIGCHLD 的信号操作设置为 SIG_IGN 或为信号设置了 SA_NOCLDWAIT 标志,也会发生这种情况。
  2. 在参数中检测到问题。如果问题出在options 参数上,errno 将被设置为EINVAL。如果pid大于0(所以你在等待一个特定的子进程)并且不存在或者不是这个进程的子进程,errno将被设置为ECHILD;如果您处于等待循环中,这可能不适用。这些通常表明您的代码存在问题,您应该报告或记录它,然后退出。
  3. 呼叫被信号中断。 errno 将设置为 EINTR。发生这种情况时,您可能应该留在循环中。

【讨论】:

  • 好的,谢谢您的回答。第一部分让我感到困惑,因为手册页只明确提到了 wait() 的情况,而不是 waitpid() 或 waitid()。顺便说一句,将 pid 参数设置为 0 只会收获具有相同组 ID 的进程,因此不一定具有与将其设置为 -1 相同的行为。
  • 您的手册页必须与我的不同。在我的,关于waitpid 的段落说If there are no children not previously awaited, -1 is returned with errno set to [ECHILD].
  • 我并没有说-10 具有相同的行为,只是他们不等待特定的孩子。当您等待特定的孩子时,ECHILD 表示该孩子无效;当您等待任何孩子或组中的任何孩子时,ECHILD 表示没有任何剩余。
  • 如果waitpid()确实等待一个孩子并且或者sigaction for ECHLD设置为SIG_IGNSA_NOCLDWAIT 标志已设置。请参阅wait() 的手册页。
  • @abligh 谢谢,已添加到答案中。
猜你喜欢
  • 1970-01-01
  • 2014-02-28
  • 2015-04-16
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 2021-01-31
相关资源
最近更新 更多