在寻找显示tcsetpgrp()
调用用法的代码片段时,我遇到了https://www.ibm.com/support/knowledgecenter/SSLTBW_2.3.0/com.ibm.zos.v2r3.bpxbd00/rttcsp.htm,其中显示了CELEBT10.c的代码。
当执行我得到的代码
original foreground process group id of stdout was 59741
now setting to 59742
则程序停止。
对于ps -aj
,我看到组更改(setpgid()
)工作正常,实际上,当我向子进程发送SIGCONT
信号时,子进程执行剩余部分并退出(与等待的父进程一起)。
在tcsetpgrp()
之后添加一个sleep()
,ps -aj
也显示父组仍然是前台组,即tcsetpgrp()
调用失败。
有人能解释一下为什么子进程在tcsetpgrp()
调用中停止以及为什么失败吗?
1条答案
按热度按时间ax6ht2ek1#
这是因为从后台进程 * 尝试
tcsetpgrp
* 生成了SIGTTOU
,如手册中所述:如果tcsetpgrp()从后台进程组针对调用者的控制终端被调用,则SIGTTOU信号可以根据进程如何处理SIGTTOU而被生成:通过运行'strace -f ./a.out'并观察子进程的输出('-f'表示跟随fork),您可以看到这一点:
tcsetpgrp()
被库转换为ioctl
,我们可以看到发生了什么。将指向的代码复制到此处:
参见注解“未注解我”,它将允许功能继续:
我已经很久没有这么做了,所以我对基本原理有点模糊,但我相信这个想法是后台进程不应该写终端,也不应该把前台进程正在做的事情搞砸。很多时候,把自己放在后台的代码会重定向它的输入/输出,把自己从前台终端分离出来。
通过捕捉(或忽略)信号,代码使其意图明确,但我不确定随意的“忽略信号”是否自动是正确的答案;我们需要了解这些代码如何融入大局。