title: How can I effectively use boost::process::async_pipe for both writing and reading?
body: <p>I've already seen the <a href="https://www.boost.org/doc/libs/1_75_0/doc/html/boost_process/tutorial.html" rel="nofollow noreferrer">boost::process tutorial</a>... but there the example is a single write then a single read from the child process. I want to know if it is possible to have both async_pipes alive (read and write) during the child process lifetime.</p>
  <p>I'm having trouble reading from child-&gt;parent pipe (<code>read_pipe</code>, in my code). I can only read from it after closing the parent-&gt;child pipe (<code>write_pipe</code>), but that means that I won't write anything ever again on this child process, right? This makes sense, but there is some workaround to maintain a bi-directional channel? My final objective is to continuously alternate between reading and writing chunks.</p>
  <pre><code>#include &lt;boost/asio.hpp&gt;
  #include &lt;boost/process.hpp&gt;
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;vector&gt;
  
  typedef std::function&lt;void(const boost::system::error_code &amp; ec, std::size_t n)&gt; Handler;
  
  int main(){
      
      std::vector&lt;char&gt; 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(  &quot;stockfish_12_win_x64/stockfish_20090216_x64.exe&quot; , 
                                                  boost::process::std_in  &lt;  write_pipe ,
                                                  boost::process::std_out &gt;  read_pipe  );
      
  
      Handler on_stdout,on_stdin;
      std::string read_string;
  
      on_stdout = [&amp;](const boost::system::error_code &amp; ec, size_t n){
          std::cout &lt;&lt; &quot;I'm reading &quot; &lt;&lt; n &lt;&lt; &quot; characters from the child process. Can't wait for more!&quot; &lt;&lt; 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 = [&amp;]( const boost::system::error_code &amp; ec, std::size_t n ){
          std::cout &lt;&lt; &quot;I know that &quot; &lt;&lt; n &lt;&lt; &quot; characters were sent to the process. Yay! &quot; &lt;&lt; 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 &quot;on_stdin&quot; handler being called... and it was!
      std::string write_string = &quot;uci\n&quot;;
      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();
  
      
  }
  </code></pre>