从 boost::process 到 boost::child 的信号传播

Posted

技术标签:

【中文标题】从 boost::process 到 boost::child 的信号传播【英文标题】:signal propagation from boost::process to boost::child 【发布时间】:2018-04-11 10:59:30 【问题描述】:

我在 Linux 的主应用程序中使用 boost::process v. 1.65.1 来创建少量 boost::process::child 对象并管理通过 boost::process::std_inboost::process::std_out 交换的数据,即管道。

当我的主应用程序收到控制台发送的 CTRL-C 时,我看到子应用程序也收到了 CTRL-C 信号。

要终止我的孩子,我更愿意通过管道发送一个明确的命令,但是当我这样做时,信号已经被传播了。实际上,有些孩子看到了其他孩子没有看到的命令并看到了信号。

    这种信号传播是正常行为吗? 我可以做些什么来防止这种情况发生,以便我可以通过管道发出我的命令而不受干扰?

【问题讨论】:

【参考方案1】:

这种信号传播是正常行为吗?

这本身不是传播,而是当您在 POSIX 终端中键入 Ctrl+C 时,SIGINT 信号会广播到 所有进程 终端的前台进程组。进程组由 shell 管理,默认情况下,分叉处理的保留在父组 (source) 中。

我可以做些什么来防止这种情况发生,以便我可以通过管道发出我的命令而不受干扰?

在子进程中拦截SIGINT 并执行必要的清理:

#include <boost/asio/signal_set.hpp>
#include <iostream>

void exit_handler(const boost::system::error_code&, int signal_number)

  std::cerr << "Signal " << signal_number << "!\n";
  exit(1);


int main()

  boost::asio::io_service io_service;

  boost::asio::signal_set signals(io_service, SIGINT);

  signals.async_wait( exit_handler );

  io_service.run();

同时考虑其他信号可能是个好主意(HUPTERM)。

【讨论】:

感谢您的回复。事实上,我有 2 个问题。第一个就是这样。我希望我的应用程序在通过管道接收到的命令时退出,所以可能在那个信号处理程序中我不应该调用 std::exit。第二个更大,是我使用 linux 'poll' 从控制台读取。如果我喜欢你说“轮询”,它应该读取 STOP 命令,返回信号并且不读取。我能为这种情况做些什么?您认为信号屏蔽可能是一种选择吗?我从未使用过它们,但我知道这可以防止信号被完全忽略。

以上是关于从 boost::process 到 boost::child 的信号传播的主要内容,如果未能解决你的问题,请参考以下文章

使用 boost::process 读取 cout 并写入进程的 cin

Boost.Process - 如何让一个进程运行一个函数?

带有标准输出重定向的`boost :: process`在Ubuntu 16中随机失败

Windows 上的 Boost::process - 使用 MinGW?

Boost::process child by id

Boost:如何处理其嵌套的包含文件?