- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
注意:我在本文中交替使用“客户端”和“子”这两个词来指代从“服务器”启动的进程。
我正在使用 boost::process::async_pipe 编写我使用 boost::process::child 启动的进程的 STDIN。假设我的服务器程序看起来像这样:
(这不是一个有效的服务器演示)
服务器.cpp
int main()
{
using namespace std::chrono_literals;
boost::process::async_pipe writePipe;
boost::process::child child { "client", boost::process::std_in < _writePipe };
std::vector<char> buffer;
buffer.resize(1024u * 1024u);
while (working)
{
auto length = 0u;
/*
do a bunch of work that takes a long time
and also determines `length`, in this case I'm
adding a sleep to simulate the time between
calls to `async_write()`
*/
std::this_thread::sleep_for(5s);
boost::asio::async_write(writePipe,
boost::asio::buffer(buffer.data(), length),
[&writePipe](boost::system::error_code, size_t)
{
// writePipe.close();
});
/*
I know that this code as-is would have issues with
synchronizing `buffer`, but for the purpose of this
question please ignore that
*/
}
}
基本上我有一个内存缓冲区,我在其中做一些工作,并且我经常想向子进程发送一些二进制数据。我的子进程看起来像这样:
child .cpp
#include <iostream>
#include <string_view>
void print_hex(const char* p, std::size_t size)
{
std::string_view input(p, size);
static const char* const lut = "0123456789ABCDEF";
size_t len = input.length();
std::string output;
output.reserve(2 * len);
for (size_t i = 0; i < len; ++i)
{
const unsigned char c = static_cast<const unsigned char>(input[i]);
// output.append("0x");
output.push_back(lut[c >> 4]);
output.push_back(lut[c & 15]);
output.append(" ");
}
if (output.size() > 0) output.pop_back();
std::cout << "HEX (" << size<< "): " << output << std::endl;
}
int main()
{
std::vector<char> buffer;
buffer.resize(BUFFER_SIZE);
bool done = false;
while (!done)
{
auto rdbuf = std::cin.rdbuf();
while (auto count = rdbuf->sgetn(buffer.data(), BUFFER_SIZE))
{
print_hex(buffer.data(), count);
}
}
}
随着 writePipe.close()
被注释掉,我注意到我的子程序在服务器进程终止之前从未获得任何数据。如果我取消注释关闭管道的调用,那么我只能处理第一次调用 boost::asio::async_write()
时的数据。
编辑:
不幸的是@sehe 的原始答案没有解决问题。我稍微更新了服务器代码以更好地说明问题(并且我解决了保留/调整大小问题)。
然而,当再次环顾四周时,我读到了一些关于 sgetn()
的语言,它说:
The default definition of xsgetn in streambuf retrieves charactersfrom the controlled input sequence and stores them in the arraypointed by s, until either n characters have been extracted or the endof the sequence is reached.
因此,我重构了我的客户端,首先询问流有多少字节可用,然后分块读取流。这是我的第一次尝试:
bool done = false;
while (!done)
{
auto rdbuf = std::cin.rdbuf();
const auto available = rdbuf->in_avail();
if (available == 0)
{
continue;
}
auto bytesToRead = std::min(BUFFER_SIZE, static_cast<std::uint32_t>(available));
auto bytesRead = rdbuf->sgetn(buffer.data(), bytesToRead);
print_hex(buffer.data(), bytesRead);
while (bytesRead < available)
{
bytesToRead = std::min(BUFFER_SIZE, static_cast<std::uint32_t>(available - bytesRead));
bytesRead += rdbuf->sgetn(buffer.data(), bytesToRead);
print_hex(buffer.data(), bytesRead);
}
}
但是,即使在添加了 std::cin.sync_with_stdio(false);
(来自答案 Why does in_avail() output zero even if the stream has some char? )之后,对 rdbuf->in_avail()
的调用总是返回0
。即使我在服务器外部和命令行上尝试,如:ls |客户端
我希望我的客户端程序读取传入的数据,而不必 (1) 关闭服务器进程或 (2) 关闭管道(除非我可以重新打开管道以执行后续 write
()。
谢谢!
最佳答案
哎呀。我花了很多时间调整服务器直到它工作。
原来有...客户端中的错误。
基本上,在你写 .reserve(...)
的地方你应该放 .resize()
:
buffer.resize(BUFFER_SIZE);
A similar bug also possibly exists in the server, even you don't show the full code, the reserve there seems odd.
现在,我不确定服务器部分实际上需要多少更改,但让我把它放在我最终成功测试它的地方。
#include <boost/asio/io_service.hpp>
#include <boost/process.hpp>
#include <iostream>
#include <random>
static std::mt19937 prng{ std::random_device{}() };
static std::uniform_int_distribution<size_t> lendist(10, 32);
static std::uniform_int_distribution<char> a_z('a', 'z');
static size_t gen_length() { return lendist(prng); }
static char gen_alpha() { return a_z(prng); }
namespace bp = boost::process;
namespace ba = boost::asio;
using namespace std::chrono_literals;
int main() {
ba::io_service io; // one thread
//ba::io_service::strand strand(io);
auto& strand = io;
bp::async_pipe writePipe(io);
//bp::child child(bp::exe("/home/sehe/Projects/stackoverflow/child.exe"),
bp::child child(bp::exe("./child.exe"),
io,
bp::std_in < writePipe,
bp::std_out > "child.log");
auto shutdown_sequence = [&] {
std::this_thread::sleep_for(1s);
std::clog << "Closing" << std::endl;
post(strand, [&] { writePipe.close(); });
};
std::function<void()> work_loop;
work_loop = [&, buffer = std::vector<char>(1 << 20)]() mutable {
size_t length = gen_length();
std::generate_n(buffer.data(), length, gen_alpha);
async_write(writePipe, bp::buffer(buffer.data(), length),
[&strand, &shutdown_sequence, &work_loop](boost::system::error_code ec, size_t tx) {
std::clog << "Wrote " << tx << " bytes (" << ec.message() << ")" << std::endl;
if (ec || (tx == 29)) { // magic length indicates "work done"
post(strand, shutdown_sequence);
} else {
post(strand, work_loop);
}
});
};
// start IO pump
post(strand, work_loop);
io.run();
std::clog << "Bye" << std::endl;
}
运行时,打印类似的东西
./main.exe
Wrote 13 bytes (Success)
Wrote 11 bytes (Success)
Wrote 26 bytes (Success)
Wrote 32 bytes (Success)
Wrote 17 bytes (Success)
Wrote 24 bytes (Success)
Wrote 28 bytes (Success)
Wrote 29 bytes (Success)
Closing
Bye
同时还写了一个child.log
:
HEX (32): 71 74 79 6E 77 74 66 63 74 72 66 6D 6D 69 6E 68 73 61 6F 75 68 77 69 77 6B 65 77 6F 76 6D 76 6E
HEX (32): 68 67 72 79 77 7A 74 68 6A 77 65 63 78 64 66 76 6A 61 64 7A 72 6C 74 6E 63 74 6B 71 64 73 7A 70
HEX (32): 70 73 77 79 75 61 70 7A 6D 73 6F 77 68 71 6A 6B 62 6F 77 63 70 63 6D 74 79 70 70 67 6B 64 75 63
HEX (32): 78 6A 79 65 78 68 74 69 75 7A 67 73 67 63 6D 69 73 65 64 63 67 6C 72 75 72 66 76 79 74 75 61 6F
HEX (32): 76 69 75 6D 73 76 6E 79 72 6C 77 6D 69 6F 74 71 6D 76 77 6F 6E 70 73 77 6C 6B 75 68 76 74 71 74
HEX (20): 79 71 77 77 61 75 71 6A 73 68 67 71 72 7A 77 6C 66 67 74 67
关于c++ - 使用 boost::asio::async_write 和 boost::process::async_pipe 多次写入子进程的标准输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65313352/
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 5年前关闭。 Improve t
我是一名设计老师,试图帮助学生应对编程挑战,所以我编码是为了好玩,但我不是专家。 她需要找到 mode (最常见的值)在使用耦合到 Arduino 的传感器的数据构建的数据集中,然后根据结果激活一些功
我正在开发一个应用程序,该应用程序提供 CPU 使用率最高的 5 个应用程序名称。目前,我通过以下代码获得了排名前 5 的应用程序: var _ = require('lodash');
互联网上很少有例子涉及这个问题的所有三个问题——即 set-process-sentinel ; set-process-filter ;和 start-process . 我尝试了几种不同的方法来微
如 this post 中所述,在 C# 中有两种调用另一个进程的方法。 Process.Start("hello"); 和 Process p = new Process(); p.StartInf
我试图让我的桨从白色变为渐变(线性),并使球具有径向渐变。感谢您的帮助!您可以在 void drawPaddle 中找到桨的代码。 这是我的目标: 这是我的代码: //球 int ballX = 50
考虑:流程(a)根据我的文字: A process is first entered at the time of simulation, at which time it is executed u
我真的希望 Processing 有用于处理数组的 push 和 pop 方法,但由于它没有,我不得不试图找出删除数组中特定位置的对象的最佳方法。我相信这对很多人来说都是基本的,但我可以使用一些帮助,
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
以编程方式,我如何确定 Windows 10 中的 3 个类别 应用 后台进程 Windows 服务 就像任务管理器一样? 即我需要一些 C# 代码,我可以确定应用程序列表与后台进程列表。检查 Win
当我导入 node:process它工作正常。但是,当我尝试要求相同时,它会出错。 这工作正常: import process from 'node:process'; 但是当我尝试要求相同时,它会引
我正在上一门使用处理的类(class)。 我在理解 map() 函数时遇到问题。 根据它的文档( http://www.processing.org/reference/map_.html ): Re
我试图执行: composer.phar update 并收到: Fatal error: Allowed memory size of 94371840 bytes exhausted (tried
给定一堆二维图像,如何使用 Processing/Processing.js 产生体积渲染效果? 目前我的想法是使用 java(类似于 imageJ)进行体积渲染 -> 获取体积渲染图像的面作为单独的
这是代码示例 var startInfo = new ProcessStartInfo { Arguments = commandStr, FileName = @"C:\Window
当我在 Processing(草图 > 导入库 > 添加库)中添加库时,它安装在哪里? 最佳答案 它们安装在您的 中速写本位置 . 您可以通过转到"file">“首选项”来查看和更改您的速写本位置。草
无聊的好奇... 我正在查看当前进程的一些属性: using(Process p = Process.GetCurrentProcess()) { // Inspect properties
我正在尝试在同一页面上运行多个草图。 初始化脚本指定: /* * This code searches for all the * in your page and loads each scrip
Process.Kill 后是否需要使用 Process.WaitForExit? 如果调用进程在调用 Process.Kill 后立即退出怎么办? 这会导致 Process.Kill 失败吗? 编辑
我尝试使用处理从麦克风获取频率。我混合了文档中的两个示例,但“最高”并不是真正的赫兹(a 是 440 赫兹)。 你知道如何拥有比这更好的东西吗? import ddf.minim.*; import
我是一名优秀的程序员,十分优秀!