孩子收到sigstop后,wait()不会返回

时间:2016-10-10 16:26:50

标签: c signals fork posix wait

正如标题所说的那样,一个进程分叉等待其子进行SIGSTOP(由孩子自己发送),但它并没有在它没有收到任何SIGCHLD之后醒来(但实际上它没有,用strace测试。

任何想法?

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

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

2 个答案:

答案 0 :(得分:7)

The specification for wait表示只报告退出的孩子,而不报告已停止的孩子。你应该使用

waitpid(-1, 0, WUNTRACED);

代替。

国旗名称WUNTRACED有点神秘 - 为什么不是WSTOPPED?这是标准化wait* API与非标准化ptrace API进行对比的一个方面。比较POSIX对WUNTRACED ...

的定义
  
WUNTRACED
pid指定的任何已停止的子进程的状态,以及自停止后尚未报告的状态,也应报告给请求进程。

...其文档在Linux manpage ...

  如果孩子已经停止(但没有通过ptrace(2)跟踪),
WUNTRACED
也会返回。即使未指定此选项,也会提供已停止的已跟踪子项的状态。   

所以基本上wait*的默认行为中嵌入了一个特殊情况,以方便人们编写调试器(编写调试器的人会尽可能地获取它们)并且这种特殊情况已经存在了很长时间它会影响为waitpid标志选择的名称。 (我不知道这种或那种方式,但我不会惊讶地发现ptrace停止而不是作业控制停止。)

答案 1 :(得分:0)

哎呀,我会自己回答,我忘了添加WUNTRACED作为wait()选项。 正确的函数调用是waitpid(-1,NULL,WUNTRACED);