Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is std::iostream non-blocking?

Tags:

c++

iostream

According to the boost reference for Boost.Iostreams (In section 3.6, at the very bottom):

http://www.boost.org/doc/libs/1_64_0/libs/iostreams/doc/index.html

Although the Boost.Iostreams Filter and Device concepts can accommodate non-blocking i/o, the C++ standard library stream and stream buffer interfaces cannot, since they lack a means to distinguish between temporary and permanent failures to satisfy a read or write request

However, the function std::istream::readsome appears to be non-blocking, in that the available characters will be immediately returned, without a blocking (except for a RAM copy) wait. My understanding is that:

std::istream::read will block until eof or number of characters read.

std::istream::readsome will return immediately with characters copied from the internal buffer.

like image 799
Jibbity jobby Avatar asked Aug 31 '17 20:08

Jibbity jobby


2 Answers

I agree with you that readsome is not a blocking operation. However, as specified, it is wholly inadequate as an interface for performing what is usually called "non-blocking I/O".

First, there is no guarantee that readsome will ever return new data, even if it is available. So to guarantee you actually make progress, you must use one of the blocking interfaces eventually.

Second, there is no way to know when readsome will return data. There is no way to "poll" the stream, or to get a "notification" or "event" or "callback". A usable non-blocking interface needs at least one of these.

In short, readsome appears to be a half-baked and under-specified attempt to provide a non-blocking interface to I/O streams. But I have never seen it used in production code, and I would not expect to.

I think the Boost documentation overstates the argument, because as you observe, readsome is certainly capable of distinguishing temporary from permanent failure. But their conclusion is still correct for the reasons above.

like image 73
Nemo Avatar answered Nov 06 '22 05:11

Nemo


When looking into non-blocking portability, I didn't find anything in the C++ standard library that looked like it did what you think it does.

If your goal is portability, my interpretation was that the section that mattered most was this:

http://en.cppreference.com/w/cpp/io/basic_istream/readsome

For example, when used with std::ifstream, some library implementations fill the underlying filebuf with data as soon as the file is opened (and readsome() on such implementations reads data, potentially, but not necessarily, the entire file), while other implementations only read from file when an actual input operation is requested (and readsome() issued after file opening never extracts any characters).

This says that different implementations that use the iostream interface are allowed to do their work lazily, and readsome() doesn't guarantee that the work even gets kicked off.

However, I think your interpretation that readsome is guaranteed not to block is true.

like image 37
Josh Avatar answered Nov 06 '22 04:11

Josh