【问题标题】:Close the stdin of boost::process child关闭 boost::process child 的 stdin
【发布时间】:2017-05-29 09:52:51
【问题描述】:

我正在尝试使用 Boost-1.64.0 调用带有字符串到其标准输入的进程。 当前代码是:

  bp::opstream inStream ;
  bp::ipstream outStream;
  bp::ipstream errStream;

  bp::child child(
    command, // the command line
    bp::shell,
    bp::std_out > outStream,
    bp::std_err > errStream,
    bp::std_in  < inStream);


  // read the outStream/errStream in threads

  child.wait();

问题在于子可执行文件正在等待其标准输入 EOF。这里 child.wait() 无限期挂起......

我尝试使用 asio::buffer、std_in.close()、……但没有运气。 我发现的唯一 hack 是 delete() inStream……这并不可靠。

我应该如何“通知”子进程并使用新的 boost::process 库关闭其标准输入?

谢谢!

【问题讨论】:

  • 什么意思,"delete() inStream"?这对我来说没有多大意义。

标签: c++ boost stdin boost-process


【解决方案1】:

我尝试使用 asio::buffer,std_in.close()

这行得通。当然,只有将它传递给启动函数(bp::child 构造函数、bp::system 等)时它才有效。

如果您需要传递数据,然后关闭它,只需关闭关联的文件描述符即可。我做这样的事情:

boost::asio::async_write(input, bp::buffer(_stdin_data), [&input](auto ec, auto bytes_written){
    if (ec) {
        logger.log(LOG_WARNING) << "Standard input rejected: " << ec.message() << " after " << bytes_written << " bytes written";
    }
    may_fail([&] { input.close(); });
});

input 在哪里

bp::async_pipe input(ios);

另外,检查进程是否实际上没有卡住发送输出!如果您未能使用输出,它将在缓冲区已满时进行缓冲和等待。

【讨论】:

  • 你拯救了我的一周。我想 may_fail 是您的自定义异常处理程序,所以我直接调用 input.close() 。你也必须调用 ios.run() :)
  • 是的!抱歉这次复制了不完整的代码:(paste.ubuntu.com/24701992
【解决方案2】:

写完后通过调用inStream.close(); 来关闭管道。您也可以在启动时使用bp::std_in.close() 关闭它。

asio 解决方案当然也有效,避免了死锁的危险。

【讨论】:

  • 你能添加到这个答案吗? OP 使用了 boost::process::opstream 对象,它没有 close() 函数。您链接到 basic_pipe 对象的文档,它似乎不是 boost::process::opstream 的一对一替代品。
  • 你可以通过调用opstream::pipe()来访问底层管道。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 2021-11-13
  • 1970-01-01
  • 2012-07-17
相关资源
最近更新 更多