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
-
Provide a timeouted method for my streams, that checks if there any data. I need only binary interface of streams i.e.
read
andwrite
methods, so method which which returns available data amount is fine enough. -
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.
-
Mix of a previous two: provide a method for streams, that will read data from pipe buffer to
streambuf
. Its like flush forstd::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?
Best Answer
It seems that like
ratchet freak
said in comments, the best solution is to use asynchronous IO. And i'm going to useboost::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