簡體   English   中英

boost::process::child 關閉輸入后不會退出 stream

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM