c - child 收到 sigstop 后 wait() 不返回

标签 c signals fork posix wait

正如标题所说,一个进程fork等待它的 child 收到一个SIGSTOP( child 自己发送的)但是它并没有在之后像没有收到任何SIGCHLD一样醒来(但它确实收到了,经过测试用 strace)。

有人有什么想法吗?

int main() {
  if (fork()) {
    wait(NULL);
    write(1, "Bye\n", 4);
  } else {
    kill(getpid(), SIGSTOP);
    write(1, "Hello\n", 6);
  }
return 0;
}

他们都挂了,而只有 child 应该挂。

最佳答案

The specification for wait说它只报告已经退出的 child ,而不是已经停止的 child 。你应该使用

waitpid(-1, 0, WUNTRACED);

相反。

标志名称 WUNTRACED 有点神秘 - 为什么不是 WSTOPPED?这是标准化的 wait* API 与非标准化的 ptrace API 擦肩而过的地方。比较 POSIX 对 WUNTRACED 的定义……

WUNTRACED
The status of any child processes specified by pid that are stopped, and whose status has not yet been reported since they stopped, shall also be reported to the requesting process.

... 及其文档在 Linux manpage 中……

WUNTRACED
also return if a child has stopped (but not traced via ptrace(2)). Status for traced children which have stopped is provided even if this option is not specified.

所以基本上 wait* 的默认行为有一个特例嵌入其中,以方便编写调试器的人(编写调试器的人会利用他们可以获得的一切便利)并且那个特例已经很长一段时间以来,它影响了为 waitpid 的标志选择的名称。 (我不知道是哪一种方式,但如果得知 ptrace 停止比作业控制停止更早,我不会感到惊讶。)

关于c - child 收到 sigstop 后 wait() 不返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39962707/

相关文章:

C 使用现有的 const 变量初始化 const struct 成员

无法从温度计字节读数中提取整数

c - C 中的 fork 和指针

perl - 在 mod_perl2 下 fork 是个坏主意吗?

c - 文件结束标记/文件扫描

c - C 中的数组传递

c - 使用写入或异步安全函数从信号处理程序打印 int

c - OSX 与 Linux 上的 pselect() 行为有何不同?

Perl IPC::运行,在父进程死亡时终止进程

c - 用execl中的变量替换字符串值并停止执行