首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何有效地使用boost::process::async_pipe进行写入和读取?

如何有效地使用boost::process::async_pipe进行写入和读取?
EN

Stack Overflow用户
提问于 2021-02-11 10:36:57
回答 1查看 408关注 0票数 1

我已经看过boost::process tutorial了..。但在这里,示例是从子进程进行一次写入,然后一次读取。我想知道是否有可能在子进程生命周期中同时激活(读和写) async_pipes。

我在读取子->父管道(在我的代码中是read_pipe)时遇到了问题。我只能在关闭父->子管道(write_pipe)之后才能读取它,但这意味着我再也不会在这个子进程上写任何东西了,对吧?这是有道理的,但是有一些解决办法来维护双向通道?我的最终目标是不断地在读和写块之间交替。

代码语言:javascript
运行
复制
#include <boost/asio.hpp>
#include <boost/process.hpp>
#include <iostream>
#include <string>
#include <vector>

typedef std::function<void(const boost::system::error_code & ec, std::size_t n)> Handler;

int main(){
    
    std::vector<char> vread_buffer(4096);
    boost::asio::io_service ios;
    boost::process::async_pipe read_pipe{ios};
    boost::process::async_pipe write_pipe{ios};
    auto child_process = boost::process::child(  "stockfish_12_win_x64/stockfish_20090216_x64.exe" , 
                                                boost::process::std_in  <  write_pipe ,
                                                boost::process::std_out >  read_pipe  );
    

    Handler on_stdout,on_stdin;
    std::string read_string;

    on_stdout = [&](const boost::system::error_code & ec, size_t n){
        std::cout << "I'm reading " << n << " characters from the child process. Can't wait for more!" << std::endl;
        read_string.reserve( read_string.size() + n );
        read_string.insert( read_string.end() , vread_buffer.begin() , vread_buffer.begin() + n );
        if(!ec) boost::asio::async_read( read_pipe , boost::asio::buffer(vread_buffer) , on_stdout );
    };
    on_stdin = [&]( const boost::system::error_code & ec, std::size_t n ){
        std::cout << "I know that " << n << " characters were sent to the process. Yay! " << std::endl;
    };

    // {...} Suppose an undefined amount of time has passed 

    // Expected: To see the initial print from the program calling the on_stdout
    // ... but it doesn't call anything.
    boost::asio::async_read( read_pipe , boost::asio::buffer(vread_buffer) ,  on_stdout );
    ios.poll();
    ios.restart();


    // Expected: To see the "on_stdin" handler being called... and it was!
    std::string write_string = "uci\n";
    boost::asio::async_write( write_pipe , boost::asio::buffer(write_string) ,  on_stdin );
    ios.poll();
    ios.restart();
    
    // Sending a async_read will never do anything unless I close the write_pipe.
    // How can I tell the io_service that last write was done so I can read again?
    boost::asio::async_read( read_pipe , boost::asio::buffer(vread_buffer) ,  on_stdout );
    ios.poll();
    ios.restart();

    
}
EN

回答 1

Stack Overflow用户

发布于 2021-02-12 05:27:24

我想我想通了。我应该使用传递分隔符(字符/正则表达式/字符串)的boost::asio::async_read_until,而不是boost::asio::async_read

这样,应该将boost::process::buffer更改为boost::asio::dynamic_buffer

代码语言:javascript
运行
复制
std::string read_string;
auto d_buffer = boost::asio::dynamic_buffer(read_string);

// First read
boost::asio::async_read_until( read_pipe , d_buffer  , '\n' , on_stdout );
ios.poll();
ios.restart();

// Any amount of writes can be done here with async_write

// Second read
d_buffer.consume(d_buffer.size(); // Will append new content into read_string anyway, this is just to read_string doesn't grow indefinitely. Also, I noted unexpected behavior if not consume all content (new content appended at random middle points)
boost::asio::async_read_until( read_pipe , d_buffer  , '\n' , on_stdout );
ios.poll();
ios.restart();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66148021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档