gpt4 book ai didi

c++ - 读取阻塞进程的输出

转载 作者:行者123 更新时间:2023-11-30 04:43:56 24 4
gpt4 key购买 nike

我有一些简单的应用程序:

//first.exe

int main()
{
std::cout << "1" << std::endl;
std::cout << "2" << std::endl;
std::cout << "3" << std::endl;

std::cin.get();

return 0;
}

当作为子进程运行的应用程序的标准输出中出现“2”时,我想在单独的应用程序中调用回调:

//second.exe

int main()
{
boost::asio::io_context context;
boost::process::async_pipe out(context);
boost::asio::streambuf buffer;

boost::process::child("first.exe", boost::process::std_out > out);

boost::asio::async_read_until(out, buffer, "2", [](boost::system::error_code code, std::size_t size)
{
//do something
});

context.run();

return 0;
}

问题是,由于子进程中的 std::cin.get(),我必须按父进程中的任何按钮才能使 io_context 执行回调函数。您对让它按预期工作有什么建议吗?

最佳答案

在这种情况下,我认为您不需要做任何事情(std::cin 读取可能会失败):

Live On Coliru

#include <boost/process.hpp>
#include <boost/asio.hpp>
#include <boost/process/async.hpp>
#include <iostream>
#include <iomanip>

int main()
{
namespace bp = boost::process;
boost::asio::io_context context;
bp::async_pipe out(context);

bp::child c("./first.exe", bp::std_out > out);

boost::asio::streambuf buffer;
boost::asio::async_read_until(out, buffer, "2", [&](boost::system::error_code code, std::size_t size) {
if (code) {
std::cerr << "Oops: " << code.message() << std::endl;
} else {
std::cerr << "received: " << size << " bytes: ";

auto b = buffers_begin(buffer.data()), m = b+size, e = buffers_end(buffer.data());

std::clog << std::quoted(std::string(b, m)) << std::endl;
std::clog << "Note that we read more bytes: " << std::quoted(std::string(m, e)) << std::endl;

buffer.consume(size);
}
});

context.run();
return c.exit_code();
}

打印

received: 3 bytes: "1
2"
Note that we read more bytes: "
3
"

清洁工

为了清洁,您可以简单地关闭 std_in:

bp::child c("./first.exe", bp::std_out > out, bp::std_in.close());

为了正确起见,还要为异步 io 添加上下文:

bp::child c("./first.exe", bp::std_out > out, bp::std_in.close(), context);

这些都有效(参见 live)。

更复杂

如果您实际上需要提供输入以获得输出怎么办?或者您需要根据输出提供输入?那么评论者是对的:将管道附加到 std_in(或异步写入缓冲区)。

发送固定缓冲区

Live On Coliru

  • 第一个.cpp

    #include <iostream>
    int main() {
    using namespace std;
    string s;
    while (cin >> s)
    cout << "reversed: " << string(s.rbegin(), s.rend()) << endl;
    }
  • main.cpp

    #include <boost/process.hpp>
    #include <boost/asio.hpp>
    #include <boost/process/async.hpp>
    #include <iostream>
    #include <iomanip>

    int main() {
    namespace bp = boost::process;
    boost::asio::io_context context;
    bp::async_pipe out(context);

    std::string i = "hello\nwo2rld\n";
    bp::child c("./first.exe", bp::std_out > out, bp::std_in < boost::asio::buffer(i), context);

    boost::asio::streambuf buffer;
    boost::asio::async_read_until(out, buffer, "2", [&](boost::system::error_code code, std::size_t size) {
    if (code) {
    std::cerr << "Oops: " << code.message() << std::endl;
    } else {
    std::cerr << "received: " << size << " bytes: ";

    auto b = buffers_begin(buffer.data()), m = b+size, e = buffers_end(buffer.data());

    std::clog << std::quoted(std::string(b, m)) << std::endl;
    std::clog << "Note that we read more bytes: " << std::quoted(std::string(m, e)) << std::endl;

    buffer.consume(size);
    }
    });

    context.run();
    return c.exit_code();
    }

打印

received: 30 bytes: "reversed: olleh
reversed: dlr2"
Note that we read more bytes: "ow
"

发送动态数据

同步和异步:

#include <boost/process.hpp>
#include <boost/asio.hpp>
#include <boost/process/async.hpp>
#include <iostream>
#include <iomanip>

int main() {
namespace bp = boost::process;
boost::asio::io_context context;
bp::async_pipe out(context), in(context);

bp::child c("./first.exe", bp::std_out > out, bp::std_in < in, context);

boost::asio::write(in, boost::asio::buffer("hello ", 6));

boost::asio::streambuf buffer;
boost::asio::async_read_until(out, buffer, "2", [&](boost::system::error_code code, std::size_t size) {
if (code) {
std::cerr << "Oops: " << code.message() << std::endl;
} else {
std::cerr << "received: " << size << " bytes: ";

auto b = buffers_begin(buffer.data()), m = b+size, e = buffers_end(buffer.data());

std::clog << std::quoted(std::string(b, m)) << std::endl;
std::clog << "Note that we read more bytes: " << std::quoted(std::string(m, e)) << std::endl;

buffer.consume(size);
}
});

boost::asio::async_write(in, boost::asio::buffer("wo2rld\n", 7), [&](boost::system::error_code code, std::size_t size) {
if (code) {
std::cerr << "Oops: " << code.message() << std::endl;
} else {
std::cerr << "sent: " << size << " bytes: ";
}
});

context.run();
return c.exit_code();
}

再次打印:

sent: 7 bytes: received: 30 bytes: "reversed: olleh
reversed: dlr2"
Note that we read more bytes: "ow
"

关于c++ - 读取阻塞进程的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57957558/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com