Boost.Process - 从具有休眠循环的进程读取
Boost.Process - reading from process with sleeping loop
我有一定的问题,我不确定我做错了什么。
//sleeper.exe
int main()
{
int i = 0;
while (true)
{
printf("%in", ++i);
sleep_for(1s);
}
return 0;
}
我想在我的应用程序中捕获睡眠者的输出并将其逐行添加到某个容器中;
//application.exe
int main()
{
io_context context;
async_pipe out(context);
child sleeper("sleeper.exe", std_out > out, context);
vector<string> lines;
streambuf buffer;
async_read_until(out, buffer, 'n', [](const error_code& code, size_t size)
{
// Add line to container
});
context.run();
return 0;
}
不幸的是,我的应用程序挂在context.run()
上,可能是因为卧铺应用程序永远不会终止。但是它应该读取睡眠器的输出直到分隔符,所以我不知道这里有什么问题。我期待着一些解释。
对主题进行更多研究后编辑:
根据: https://support.microsoft.com/en-us/help/190351/how-to-spawn-console-processes-with-redirected-standard-handles
注意 使用 printf(( 和 fprintf(( 等 C 运行时函数的子进程在重定向时可能表现不佳。C 运行时函数维护单独的 IO 缓冲区。重定向时,这些缓冲区可能不会在每次 IO 调用后立即刷新。因此,printf(( 调用的重定向管道的输出或 getch(( 调用的输入不会立即刷新,并且会出现延迟,有时会发生无限延迟。如果子进程在每次调用 C 运行时 IO 函数后刷新 IO 缓冲区,则可以避免此问题。只有子进程可以刷新其 C 运行时 IO 缓冲区。进程可以通过调用 fflush(( 函数来刷新其 C 运行时 IO 缓冲区。
我仍在该领域寻找解决方案。
事实上,你的卧铺程序不会终止。run()
将一直运行到完成。
让我们首先使示例"真实",以便它有一个实际的读取循环来读取超过 1 行:
std::vector<std::string> lines;
boost::asio::streambuf buffer;
std::function<void()> read_loop;
read_loop = [&] {
boost::asio::async_read_until(out, buffer, "n", [&](boost::system::error_code code, std::size_t size) {
if (code) {
std::cerr << "Oops: " << code.message() << std::endl;
} else {
std::cerr << "received: " << size << " bytes" << std::endl;
auto b = buffers_begin(buffer.data()), m = b+size;
lines.emplace_back(b, m);
buffer.consume(size);
if (lines.size()<10) {
read_loop();
}
}
});
};
read_loop();
context.run();
您可以看到它尝试读取 10 行。
终止子项
你可以杀死它:
if (lines.size()<10) {
read_loop();
} else {
c.terminate();
}
或关闭输出管道,导致相同的(管道破裂(:
if (lines.size()<10) {
read_loop();
} else {
out.close();
}
德诺
我无法让它在 Coliru 上工作,但我先用.exe替换了:
#include <iostream>
#include <chrono>
#include <thread>
#include <random>
using namespace std;
static mt19937 prng{random_device{}()};
static auto l() { return uniform_int_distribution(5,20)(prng); }
static auto c() { return uniform_int_distribution('a','z')(prng); }
int main() {
while(true) {
cout << std::string(l(), c()) << endl;
this_thread::sleep_for(chrono::seconds(1));
}
}
通过上述程序,完整:
#include <boost/process.hpp>
#include <boost/asio.hpp>
#include <boost/process/async.hpp>
#include <iostream>
#include <iomanip>
#include <regex>
int main() {
namespace bp = boost::process;
using namespace std::string_literals;
boost::asio::io_context context;
bp::async_pipe out(context);
bp::child c("./first.exe", bp::std_out > out, context);
std::vector<std::string> lines;
boost::asio::streambuf buffer;
std::function<void()> read_loop;
read_loop = [&] {
boost::asio::async_read_until(out, buffer, "n", [&](boost::system::error_code code, std::size_t size) {
if (code) {
std::cerr << "Oops: " << code.message() << std::endl;
} else {
std::cerr << "received: " << size << " bytes" << std::endl;
auto b = buffers_begin(buffer.data()), m = b+size;
lines.emplace_back(b, m);
buffer.consume(size);
if (lines.size()<10) {
read_loop();
} else {
c.terminate();
}
}
});
};
read_loop();
context.run();
for (auto& line : lines) {
std::cout << std::quoted(std::regex_replace(line, std::regex("\n"), "\n"s)) << "n";
}
return c.exit_code();
}
在我的系统上打印:
received: 19 bytes
received: 12 bytes
received: 20 bytes
received: 16 bytes
received: 6 bytes
received: 6 bytes
received: 20 bytes
received: 13 bytes
received: 16 bytes
received: 21 bytes
"dddddddddddddddddd\n"
"lllllllllll\n"
"jjjjjjjjjjjjjjjjjjj\n"
"uuuuuuuuuuuuuuu\n"
"yyyyy\n"
"wwwww\n"
"hhhhhhhhhhhhhhhhhhh\n"
"qqqqqqqqqqqq\n"
"aaaaaaaaaaaaaaa\n"
"xxxxxxxxxxxxxxxxxxxx\n"
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- boost::进程间消息队列引发错误
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 如何在C++中创建总是在循环中接受新输入的独立进程
- Boost.Process - 从具有休眠循环的进程读取
- 提升进程间:在循环中分配共享内存
- C++双向管道-在循环中尝试从子进程读取时卡住
- 多个分叉进程无限循环
- 注入的DLL主循环使进程崩溃
- 使用Windows中另一个进程的事件循环向Qt应用程序发送退出消息
- 将字符串数组传递给多个进程的 for 循环中的 CreateProcess
- 当带有while循环的进程正在运行时,缺少对话框内容
- 如何在Linux应用程序上使用C++中的终端输入中断循环/进程
- 无法在具有无限循环的 boost.python 模块中通过 Ctrl-c 杀死进程