[英]boost::process::child will not exit after closing input stream
在下面的示例中,我嘗試將一些數據寫入子進程,該子進程處理數據並將其寫入文件。 關閉 stream 后,父進程無限期地等待子進程完成。 我不知道如何表明我已經完成了數據的寫入,並且希望子進程停止閱讀並完成它正在做的任何事情。 根據文檔,調用 terminate 會發送一個SIGKILL
,我認為這不是我想要的。
我錯過了什么? 我檢查了這個問題,但我寧願首先嘗試使實際代碼與同步 IO 一起工作。
#include <boost/process.hpp>
#include <iostream>
namespace bp = boost::process;
int main(int argc, char **argv)
{
boost::process::opstream in{};
boost::process::child child("/path/to/test.py", bp::std_in < in);
in << "test1\n";
in << "test2\n";
in << "test3\n";
in << std::flush;
std::cerr << "Closing the stream…\n";
in.close();
std::cerr << "Waiting for the child to exit…\n";
child.wait(); // Parent seems to hang here.
return 0;
}
test.py 只是將數據寫入文件,如下所示:
#!/usr/local/homebrew/opt/python@3.8/bin/python3
import sys
with open("/tmp/test.txt", "w") as f:
for line in sys.stdin:
f.write(line)
檢查源代碼后,我發現關閉 stream 並沒有關閉關聯的 pipe 至少在這種情況下。 手動執行此操作確實解決了問題:
...
in.close();
in.pipe().close();
child.wait(); // Does not hang.
該文檔警告說,對子進程使用同步 IO 容易出現死鎖。
這是對異步 IO 的最小改寫:
#include <boost/process.hpp>
#include <iostream>
namespace bp = boost::process;
int main() {
boost::asio::io_context ioc;
bp::async_pipe in{ioc};
bp::child child("./test.py", bp::std_in < in, bp::std_out.close());
for (auto msg : { "test1\n", "test2\n", "test3\n" }) {
write(in, bp::buffer(msg, strlen(msg)));
}
std::cerr << "Closing the pipe…\n";
in.close();
std::cerr << "Waiting for the child to exit…\n";
ioc.run(); // already awaits completion
child.wait(); // Parent seems to hang here.
}
你可以通過做一些延遲使它更現實:
#include <boost/process.hpp>
#include <iostream>
using namespace std::chrono_literals;
namespace bp = boost::process;
int main() {
boost::asio::io_context ioc;
bp::async_pipe in{ioc};
bp::child child("./test.py", bp::std_in < in, bp::std_out.close());
std::thread th([&] {
for (auto msg : { "test1\n", "test2\n", "test3\n" }) {
write(in, bp::buffer(msg, strlen(msg)));
std::this_thread::sleep_for(1s);
}
std::cerr << "Closing the pipe…\n";
in.close();
});
std::cerr << "Waiting for the child to exit…\n";
ioc.run(); // already awaits completion
th.join();
child.wait(); // Parent seems to hang here.
}
對於成熟的異步 IO,請參見其他示例:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.