我有一些简单的应用程序:
//first.exe
int main()
{
std::cout << "1" << std::endl;
std::cout << "2" << std::endl;
std::cout << "3" << std::endl;
std::cin.get();
return 0;
}
并且我想在作为子进程运行的应用程序的stdout中出现“ 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执行回调函数。您是否有任何建议使其按预期工作?
答案 0 :(得分:1)
在这种情况下,我认为您不需要做任何事情(std::cin
读取可能会失败):
#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(或使缓冲区被异步写入)。
first.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
"