使用 BOOST 进程在单独的线程中读取子进程标准输出

2024-03-13

我有一个主程序,它使用 boost 进程库来生成一个打印的子进程

Hello World !

每 5 秒在其标准输出上一次。

我想在主进程中的子进程的标准输出可用时读取/监视它,并在主程序中执行其他操作。

我已经尝试过这些例子boost asynchronous IO (http://www.boost.org/doc/libs/1_66_0/doc/html/boost_process/tutorial.html http://www.boost.org/doc/libs/1_66_0/doc/html/boost_process/tutorial.html)但是所有这些似乎都会阻塞主程序,直到子进程退出。

我们是否需要在单独的线程中读取孩子的标准输出?有人可以提供一个示例,其中主程序可以同时执行其他操作而不是阻止子程序的标准输出吗?


我已经尝试过 boost 异步 IO 的示例(http://www.boost.org/doc/libs/1_66_0/doc/html/boost_process/tutorial.html http://www.boost.org/doc/libs/1_66_0/doc/html/boost_process/tutorial.html)但是所有这些似乎都会阻塞主程序,直到子进程退出。

再看看。以下所有样本异步I/O http://www.boost.org/doc/libs/1_66_0/doc/html/boost_process/tutorial.html#boost_process.tutorial.async_io应该可以帮助您选择适合您的方法。

我们是否需要在单独的线程中读取孩子的标准输出?有人可以提供一个示例,其中主程序可以同时执行其他操作而不是阻止子程序的标准输出吗?

不,你不need到。虽然你can根据您想要实现的目标,这可能是最简单的事情。

同步

您未能告诉我们您想要做什么,所以我们假设您只想打印输出:

Live On Coliru http://coliru.stacked-crooked.com/a/6fd0283d9c0c98de:

bp::child c("/bin/bash", std::vector<std::string> { "-c", "for a in {1..10}; do sleep 2; echo 'Hello World !'; done" });
c.wait();

这是同步的,所以你不能同时做工作

使用读者线程

这就像:

Live On Coliru http://coliru.stacked-crooked.com/a/a76e3298e410e4fe:

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

namespace bp = boost::process;

int main() {
    bp::ipstream output;
    std::thread reader([&output] {
        std::string line;
        while (std::getline(output, line))
            std::cout << "Received: '" << line << "'" << std::endl;
    });

    bp::child c("/bin/bash",
        std::vector<std::string> { "-c", "for a in {1..10}; do sleep 2; echo 'Hello World ('$a')!'; done" },
        bp::std_out > output);

    while (c.running()) {
        std::this_thread::sleep_for(std::chrono::milliseconds(2793));
        std::cout << "(main thread working)" << std::endl;
    }

    std::cout << "(done)" << std::endl;
    c.wait();

    output.pipe().close();
    reader.join();
}

Prints (Live On Coliru http://coliru.stacked-crooked.com/a/a76e3298e410e4fe):

Received: 'Hello World (1)!'
(main thread working)
Received: 'Hello World (2)!'
(main thread working)
Received: 'Hello World (3)!'
Received: 'Hello World (4)!'
(main thread working)
Received: 'Hello World (5)!'
(main thread working)
Received: 'Hello World (6)!'
(main thread working)
Received: 'Hello World (7)!'
Received: 'Hello World (8)!'
(main thread working)
Received: 'Hello World (9)!'
(main thread working)
Received: 'Hello World (10)!'
(main thread working)
(done)

异步IO

不使用线程(好吧,只是主线程),可能看起来像:

Live On Coliru http://coliru.stacked-crooked.com/a/7874ca9c396a12a2

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

namespace bp = boost::process;

struct OtherWork {
    using clock = std::chrono::high_resolution_clock;

    OtherWork(boost::asio::io_context& io) : timer(io) { }

    void start() {
        timer.expires_at(clock::time_point::max());
        loop();
    }

    void stop() {
        timer.expires_at(clock::time_point::min());
    }

  private:
    void loop() {
        if (timer.expires_at() == clock::time_point::min()) {
            std::cout << "(done)" << std::endl;
            return;
        }

        timer.expires_from_now(std::chrono::milliseconds(2793));
        timer.async_wait([=](boost::system::error_code ec) {
            if (!ec) {
                std::cout << "(other work in progress)" << std::endl;
                start();
            } else {
                std::cout << "(" << ec.message() << ")" << std::endl;
            }
        });
    }

    boost::asio::high_resolution_timer timer;
};

int main() {
    boost::asio::io_context io;
    bp::async_pipe output(io);

    OtherWork mainwork{io};

    bp::child c("/bin/bash", std::vector<std::string> { "-c", "for a in {1..10}; do sleep 2; echo 'Hello World ('$a')!'; done" },
            bp::std_out > output, io, bp::on_exit([&mainwork,&output](auto...) {
                    output.close();
                    mainwork.stop();
                }));

    std::function<void()> readloop = [&,buffer=std::array<char, 32>{}]() mutable {
        output.async_read_some(bp::buffer(buffer), [&](boost::system::error_code ec, size_t transferred) {
                if (transferred) {
                    std::cout << "Received: '";
                    while (transferred && buffer[transferred-1] == '\n') // strip newline(s)
                        --transferred;
                    std::cout.write(buffer.data(), transferred);
                    std::cout << "'" << std::endl;
                }

                if (ec)
                    std::cout << "Output pipe: " << ec.message() << std::endl;
                else
                    readloop();
            });
    };

    mainwork.start();
    readloop();
    io.run();
}

Prints Live On Coliru http://coliru.stacked-crooked.com/a/7874ca9c396a12a2

Received: 'Hello World (1)!'
(other work in progress)
Received: 'Hello World (2)!'
(other work in progress)
Received: 'Hello World (3)!'
Received: 'Hello World (4)!'
(other work in progress)
Received: 'Hello World (5)!'
(other work in progress)
Received: 'Hello World (6)!'
(other work in progress)
Received: 'Hello World (7)!'
Received: 'Hello World (8)!'
(other work in progress)
Received: 'Hello World (9)!'
(other work in progress)
Received: 'Hello World (10)!'
Output pipe: End of file
Child exited with code=0(Success)
(Operation canceled)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 BOOST 进程在单独的线程中读取子进程标准输出 的相关文章

  • 具有子列表属性映射问题的自动映射器

    我有以下型号 Models public class Dish Required public Int64 ID get set Required public string Name get set Required public str
  • OpenCv读/写视频色差

    我试图简单地使用 openCV 打开视频 处理帧并将处理后的帧写入新的视频文件 我的问题是 即使我根本不处理帧 只是打开视频 使用 VideoCapture 读取帧并使用 VideoWriter 将它们写入新文件 输出文件看起来比输入更 绿
  • C#动态支持吗?

    看完之后这个帖子 https stackoverflow com questions 2674906 when should one use dynamic keyword in c sharp 4 0k和链接 我还有 2 个问题 问题 1
  • 使用post方法将多个参数发送到asp.net core 3 mvc操作

    使用 http post 方法向 asp net mvc core 3 操作发送具有多个参数的 ajax 请求时存在问题 参数不绑定 在 dot net 框架 asp net web api 中存在类似的限制 但在 asp net mvc
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • 如何从 C# 控制器重定向到外部 url

    我使用 C 控制器作为网络服务 在其中我想将用户重定向到外部网址 我该怎么做 Tried System Web HttpContext Current Response Redirect 但没有成功 使用控制器的重定向 http msdn
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • C 语言中 =+(等于加)是什么意思?

    我碰到 与标准相反 今天在一些 C 代码中 我不太确定这里发生了什么 我在文档中也找不到它 In ancientC 版本 相当于 它的残余物与最早的恐龙骨头一起被发现 例如 B 引入了广义赋值运算符 使用x y to add y to x
  • 如何重置捕获像素的值

    我正在尝试创建一个 C 函数 该函数返回屏幕截图位图中每四个像素的 R G 和 B 值 这是我的代码的一部分 for int ix 4 ix lt 1366 ix ix 4 x x 4 for int iy 3 iy lt 768 iy i
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 生产代码中的 LRU 实现

    我有一些 C 代码 需要使用 LRU 技术实现缓存替换 目前我知道两种实现LRU缓存替换的方法 每次访问缓存数据时使用时间戳 最后比较替换时的时间戳 使用缓存项的堆栈 如果最近访问过它们 则将它们移动到顶部 因此最后底部将包含 LRU 候选
  • 如何在c#中的内部类中访问外部类的变量[重复]

    这个问题在这里已经有答案了 我有两个类 我需要声明两个类共有的变量 如果是嵌套类 我需要访问内部类中的外部类变量 请给我一个更好的方法来在 C 中做到这一点 示例代码 Class A int a Class B Need to access
  • 通过 NHibernate 进行查询,无需 N+1 - 包含示例

    我有一个 N 1 问题 我不知道如何解决它 可以在这个问题的底部找到完全可重复的样本 因此 如果您愿意 请创建数据库 设置 NUnit 测试和所有附带的类 并尝试在本地消除 N 1 这是我遇到的真实问题的匿名版本 众所周知 这段代码对于帮助
  • 如何挤出平面 2D 网格并赋予其深度

    我有一组共面 连接的三角形 即二维网格 现在我需要将其在 z 轴上挤出几个单位 网格由一组顶点定义 渲染器通过与三角形数组匹配来理解这些顶点 网格示例 顶点 0 0 0 10 0 0 10 10 0 0 10 0 所以这里我们有一个二维正方
  • 有没有一种简单的方法可以让 Visual Studio 2015 使用特定的 ToolsVersion?

    使用特定版本构建项目或解决方案时msbuild我可以使用以下命令选择早期的 net 工具链 toolsversion or tv switch C Program Files x86 MSBuild 14 0 bin msbuild tv
  • 耐用功能是否适合大量活动?

    我有一个场景 需要计算 500k 活动 都是小算盘 由于限制 我只能同时计算 30 个 想象一下下面的简单示例 FunctionName Crawl public static async Task
  • 使用 C# 从 DateTime 获取日期

    愚蠢的问题 给定日期时间中的日期 我知道它是星期二 例如我如何知道它的 tue 2 和 mon 1 等 Thanks 您正在寻找星期几 http msdn microsoft com en us library system datetim
  • 使用 CSharpCodeProvider 类编译 C# 7.3 的 C# 编译器版本是什么?

    我想使用 Microsoft CSharp CSharpCodeProvider 类来编译 C 7 3 代码 编译器版本在 IDictionary 中指定 在创建新的 CSharpCodeProvider 时将其作为输入 例如 Compil
  • Googletest:如何异步运行测试?

    考虑到一个包含数千个测试的大型项目 其中一些测试需要几分钟才能完成 如果按顺序执行 整套测试需要一个多小时才能完成 通过并行执行测试可以减少测试时间 据我所知 没有办法直接从 googletest mock 做到这一点 就像 async选项
  • 实例化 Microsoft.Office.Interop.Excel.Application 对象时出现错误:800700c1

    实例化 Microsoft Office Interop Excel Application 以从 winforms 应用程序生成 Excel 时 出现以下错误 这之前是有效的 但突然间它停止工作了 尽管代码和 Excel 版本没有变化 我

随机推荐

  • 如何在黑莓中裁剪特定形状的图像?

    大家好 感谢阅读我的回答希望你能帮助我 我正在黑莓手机上进行图像裁剪 在我的应用程序中包含 3 个主要内容 1 将图像加载到屏幕上 2 选择裁剪区域的形状 3 在下一个屏幕上显示裁剪图像而不丢失其形状 第1步 我可以完成图像加载部分 步骤2
  • Tweepy:现在可以使用 Twitter 搜索 api 获取旧推文了吗?

    根据http www theverge com 2014 11 18 7242477 twitter search now lets you find any tweet ever sent http www theverge com 20
  • 使用批处理文件按键盘按键[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我正在尝试开发一个批处理文件 它可以自动按向左箭头和向右箭头键 n 次 中间有一些暂停 有人可以帮我解决这个问题吗 P
  • 如何避免在 Scala 中调用 asInstanceOf

    这是我的代码的简化版本 怎样才能避免打电话asInstanceOf 因为这是一个设计不佳的解决方案的味道 sealed trait Location final case class Single bucket String extends
  • 使用框架会妨碍我掌握 JavaScript 吗?

    如果我一直用框架 自己什么都不做 我怎么能成为 JavaScript 高手呢 我问了一个关于 JavaScript 的问题 每个人都建议我使用框架 它不会向我展示 JS 的真正核心 而不是手动编码 你在自己发现JS的时候有没有编写自己的所谓
  • JavaFX 嵌套控制器 (FXML )

    In this http docs oracle com javafx 2 api javafx fxml doc files introduction to fxml html nested controllers教程中 有一个示例说明如
  • PHP foreach 循环中的多个索引变量

    是否有可能有一个foreach在 PHP 中使用多个 索引 变量循环 类似于以下内容 未使用正确的语法 foreach courses as course sections as section 如果没有 有没有好的方法可以达到相同的结果
  • springboot + webpack 开发服务器,重建后不会更改 localhost 捆绑文件

    点击这张图片 请阅读下面的内容 https i stack imgur com BYXDA png 1 第一张图片是运行 webpack dev server hot inline 之后的 第二张图片是我的html 我调用js文件的方式 我
  • 如何在 Xcode 8/Swift 3 中创建 iOS liveView [重复]

    这个问题在这里已经有答案了 我不知道如何在 Xcode 8 Swift 3 Playground 中创建和显示实时视图 如果 Apple 有关于 Playground 和实时视图的综合文档 我找不到它 而且我所有的在线搜索都显示 Xcode
  • 为什么OpenGL最初要设计成状态机?[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 处理 RequireJS require 函数中的先决条件加载失败

    我正在使用 AMD 的 RequireJS 使用这段代码 我在确保module1已加载 require module1 function module1 if module1 My function code 在某些情况下module1不可
  • 如何使用 ClientID 和 ClientSecret 在 Phonegap 内使用 Angularjs 登录 Google OAuth2

    我正在尝试使用 Angularjs 使用 Ionic 框架 通过 Google OAuth2 从我的 Phonegap 应用程序登录 目前我正在使用http phonegap tips com articles google api oau
  • Android蓝牙RSSI值总是返回-32768?

    我试图通过单击按钮获取已连接蓝牙设备的当前 RSSI 值 然而它总是只返回 32768 不知道出了什么问题 不过 我在第一次连接时就能够获得正确的 RSSI private Button OnClickListener buttonRSSI
  • 如何在反应本机模式中调暗背景?

    以下是我创建的反应本机模态 但仍然找不到如何调暗背景并在弹出模态周围透明 我没有使用任何外部库 并试图在没有库的情况下找到解决方案 是否可以用这种方式来做 我的模态组件 render let modal this state modalTy
  • Xpath 获取第二个 url 以及 href 标签中的匹配文本

    一个html页面有分页链接 1个设置在页面顶部 另一个设置在页面底部 使用 HtmlUnit 我目前正在使用页面上获取 HtmlAnchorgetByAnchorText 1 顶部的某些链接存在问题 因此我想使用 XPath 引用底部链接
  • svn 与 git 浅(稀疏)签出 - 分支、提交

    我有一个非常大的网络项目 有很多 pdf 图像 php 文件 我将文件作为单个项目导入到 svn 中 我使用 svn 浅签出来签出子树的一部分 然后使用工作副本中的分支和标记等来节省空间并加快签出时间 我想知道这是否可以用 git 实现 我
  • 如何在IOS7中使#key和@key可点击

    任何人都知道如何在 IOS7 中的评论文本中使 KEY 和 NAME 可点击 例如 instagram 的做法相同 我正在尝试使用 NSMutableAttributedString 但我不确定如何检测单击事件 在下图中单击 Usernam
  • Windows 上与 taglib 的链接错误

    I built taglibWindows 的静态库如下 必须使用mingw 而不是VS 查看git clone https github com taglib taglib git git taglib 已安装cmake使用来自 cmak
  • 用C++设计事件机制

    我试图在 C 中设计一个通用的 但有些特定于用例的 事件传递机制 而不违背 新风格 C 的原则 同时又不过度使用模板 我的用例有些特殊 因为我需要完全控制事件的分发时间 事件系统是世界模拟的基础 其中世界的每次迭代都会作用于前一帧生成的事件
  • 使用 BOOST 进程在单独的线程中读取子进程标准输出

    我有一个主程序 它使用 boost 进程库来生成一个打印的子进程 Hello World 每 5 秒在其标准输出上一次 我想在主进程中的子进程的标准输出可用时读取 监视它 并在主程序中执行其他操作 我已经尝试过这些例子boost async