【问题标题】:Don't send SIGINT on CTRL+C to child processes but don't ignore the signal itself不要在 CTRL+C 上向子进程发送 SIGINT,但不要忽略信号本身
【发布时间】:2018-01-15 14:59:28
【问题描述】:

我正在尝试写一个任务控制程序,很像Supervisor。

我从一个配置文件运行一些程序并让它们在后台运行,而在主进程中我读取并执行其他命令。

在fork()-ing之前,在我调用的主进程中:

sigaction(SIGINT, &the_handler, NULL);

the_handler 存储一个简单打印函数的引用。

当按下 CTRL+C 时,子进程也会被中断(这是我不想要的)。 我可以在子进程中 fork 后运行:signal(SIGINT, SIG_IGN); 忽略它,但我希望仍然能够在 bash 中运行此命令:$ kill -n 2 <child_pid>,意思是,我不想忽略它,对吧?

那么,如何忽略 CTRL+C 到子进程的 SIGINT,但仍然能够通过其他方式接收信号呢?还是我错过了什么?

【问题讨论】:

  • 这有点像 x/y 问题。您显然不想更改孩子对信号的接收,而是阻止终端会话从 Ctrl 按键向孩子发送 SIGINT。这是使用setsid或daemon完成的

标签: c signals child-process


【解决方案1】:

这样做的传统方法是分叉两次。祖父母分叉它的孩子,然后等待他们。然后每个孩子分叉并立即退出。因为他们的父母已经退出,孙子女成为 pid 1 的父母。因此发送给祖父母的信号不会传播给前孙子女。

更多详细信息请参阅此答案

https://stackoverflow.com/a/26418006/169346

ETA:您需要在两个分叉之间调用setsid(),否则孙子仍与祖父在同一个process group 中,并且仍会收到祖父收到的信号。

【讨论】:

  • 如果我只fork() 一次并在子进程中调用setsid() 就可以了。我错过了什么吗?
  • @EmilTerman setsid 是阻止信号传播的原因。双分叉是阻止祖父母为孙子女wait 的原因,否则,如果父进程退出,当孩子退出时,他们就会变成僵尸。
  • 如果父进程退出,子进程的父进程会变成init,所以他们不会变成僵尸。
猜你喜欢
  • 2012-10-08
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
  • 2016-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-20
相关资源
最近更新 更多