2

I want to write small library to guide a child process for a specific needs (not trying to reinvent bicycle here).

My needs includes reading from child stdout and stderr. I want to implement this as streams. If I would use simple std::streambuf descendant that reads directly from pipe on underflow - then my stdout and stderr streams would block on read when there is no data available. I want to evade this, and so far I have two ideas

  1. Provide a timeouted method for my streams, that checks if there any data. I need only binary interface of streams i.e. read and write methods, so method which which returns available data amount is fine enough.

  2. But wait - there is already method, with behavior which almost match my desire. std::streambuf::in_avail. What if I'll start background thread which will feed data from pipes to my streambuf? Then I could use standard stream method std::istream::readsome.

  3. Mix of a previous two: provide a method for streams, that will read data from pipe buffer to streambuf. Its like flush for std::istream. This eliminates need in a background thread.

Personally, I like the second variant better, but I feel, that it have many caveats.

Which variant is better in a terms of code readability, performance and interface usability?

5
  • how are you creating the child process? often there is a way to get its std streams and read/write to it. Commented Oct 13, 2015 at 10:32
  • The problem is - I want to provide std::istream objects for child std streams. Once library user call child_stdout.read(1024), he wont gain control until child provide him 1024 bytes. But what if child will hang? Then parent will hang too, and there is no way to break this circle. Only with three separate threads: two to read stdout and stderr and one for watchdog to kill child on timeout and thus provide eof to streams. And I want to evade this. Commented Oct 13, 2015 at 10:46
  • The solution is then to use async IO which the std::streams aren't suited to do. Commented Oct 13, 2015 at 10:55
  • Should I take a look on boost::asio then? Commented Oct 13, 2015 at 11:05
  • 1

1 Answer 1

1

It seems that like ratchet freak said in comments, the best solution is to use asynchronous IO. And i'm going to use boost::asio. It have nice support for pipes.

Windows: http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/overview/windows/stream_handle.html Posix: http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/overview/posix/stream_descriptor.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.