By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,478 Members | 1,833 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,478 IT Pros & Developers. It's quick & easy.

How to make non-blocking call to cin?

P: n/a
is it even possible or/and there is a better alternative to accept
input in a nonblocking manner?
Sep 26 '08 #1
Share this Question
Share on Google+
12 Replies


P: n/a
puzzlecracker wrote:
is it even possible or/and there is a better alternative to accept
input in a nonblocking manner?
You could try using 'peek' member function. You should get 'eof' if no
input is available, I am guessing, but don't take my word for it, RTFM
and experiment.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 26 '08 #2

P: n/a
On Sep 26, 6:09 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
puzzlecracker wrote:
is it even possible or/and there is a better alternative to accept
input in a nonblocking manner?
You could try using 'peek' member function. You should get
'eof' if no input is available, I am guessing, but don't take
my word for it, RTFM and experiment.
Peek will wait for a character is one isn't available.
Basically, peek() is like get(), except that it doesn't extract
the character from the stream.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 26 '08 #3

P: n/a
James Kanze wrote:
On Sep 26, 6:09 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>puzzlecracker wrote:
>>is it even possible or/and there is a better alternative to accept
input in a nonblocking manner?
>You could try using 'peek' member function. You should get
'eof' if no input is available, I am guessing, but don't take
my word for it, RTFM and experiment.

Peek will wait for a character is one isn't available.
Basically, peek() is like get(), except that it doesn't extract
the character from the stream.
Then it's back to the platform- or implementation-specific extensions to
the library, I guess.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 26 '08 #4

P: n/a
On Fri, 26 Sep 2008 08:50:28 -0700, puzzlecracker wrote:
is it even possible
I don't believe it is in an OS-independent way. I don't think C++ has a
notion of non-blocking I/O at all - a read failure is always simply
treated as an "error".

Maybe have a look at the Boost.Iostreams library:

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

and in particular section 3.6 (Asynchronous and Non-Blocking I/O). But I
get the impression it's not quite there yet.
or/and there is a better alternative to accept input
in a nonblocking manner?
I'm not sure what you mean here.

What are you actually trying to do? I can tell you how to put stdin into
non-blocking mode on a POSIX (e.g. Linux) terminal, if you're interested
(and also how to make it non line-buffered, which you probably want too
in that case).

--
Lionel B
Sep 26 '08 #5

P: n/a
On Sep 26, 5:55 pm, Lionel B <m...@privacy.netwrote:
On Fri, 26 Sep 2008 08:50:28 -0700, puzzlecracker wrote:
is it even possible

I don't believe it is in an OS-independent way. I don't think C++ has a
notion of non-blocking I/O at all - a read failure is always simply
treated as an "error".

Maybe have a look at the Boost.Iostreams library:

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

and in particular section 3.6 (Asynchronous and Non-Blocking I/O). But I
get the impression it's not quite there yet.
or/and there is a better alternative to accept input
in a nonblocking manner?

I'm not sure what you mean here.

What are you actually trying to do? I can tell you how to put stdin into
non-blocking mode on a POSIX (e.g. Linux) terminal, if you're interested
(and also how to make it non line-buffered, which you probably want too
in that case).

--
Lionel B
Sure, I am actually building apps on Linux, hence posix works. Can't
use boost. Please demonstrate it(please don't flame me for OT)

Thanks
Sep 27 '08 #6

P: n/a
puzzlecracker wrote:
is it even possible or/and there is a better alternative to accept
input in a nonblocking manner?
Is what possible? Ah, I see you have hidden the question in your
subject line.

If you want non-blocking I/O, you probably don't want iostreams, at
least not using standard streambufs. How would you differentiate a
"would block" condition from an end of file?

You can use non-blocking I/O, but you'd have to provide your own
streambuf object.

--
Ian Collins.
Sep 27 '08 #7

P: n/a
On Sep 27, 3:26 am, Ian Collins <ian-n...@hotmail.comwrote:

[...]
If you want non-blocking I/O, you probably don't want iostreams, at
least not using standard streambufs. How would you differentiate a
"would block" condition from an end of file?
You can use non-blocking I/O, but you'd have to provide your own
streambuf object.
Even then, you'd have to use it outside of the normal [io]stream
interface; [io]stream will memorize any "failure". Perhaps in
collaboration with istream::readsome.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 27 '08 #8

P: n/a
On Fri, 26 Sep 2008 17:48:06 -0700, puzzlecracker wrote:
On Sep 26, 5:55 pm, Lionel B <m...@privacy.netwrote:
>On Fri, 26 Sep 2008 08:50:28 -0700, puzzlecracker wrote:
is it even possible

I don't believe it is in an OS-independent way. I don't think C++ has a
notion of non-blocking I/O at all - a read failure is always simply
treated as an "error".

Maybe have a look at the Boost.Iostreams library:

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

and in particular section 3.6 (Asynchronous and Non-Blocking I/O). But
I get the impression it's not quite there yet.
or/and there is a better alternative to accept input in a nonblocking
manner?

I'm not sure what you mean here.

What are you actually trying to do? I can tell you how to put stdin
into non-blocking mode on a POSIX (e.g. Linux) terminal, if you're
interested (and also how to make it non line-buffered, which you
probably want too in that case).

Sure, I am actually building apps on Linux, hence posix works. Can't use
boost. Please demonstrate it(please don't flame me for OT)
I won't, but someone else possibly will ;)

Here's some pretty crude code - to put stdin into non-blocking mode:

#include <unistd.h>
#include <fcntl.h>

const int fd = fileno(stdin);
const int fcflags = fcntl(fd,F_GETFL);
if (fcflags<0) { ... /* handle error */}
if (fcntl(fd,F_SETFL,fcflags | O_NONBLOCK) <0) { ... /* handle error */} // set non-blocking

"man fcntl" for more info.

To un-line buffer stdin (i.e. set terminal to "raw" mode):

#include <unistd.h>
#include <termios.h>

const int fd = fileno(stdin);
termios tcflags;
if (tcgetattr(fd,&tcflags)<0) { ... /* handle error */}
tcflags.c_lflag &= ~ICANON; // set raw mode (unset canonical modes)
if (tcsetattr(fd,TCSANOW,&tcflags)<0) { ... /* handle error */}

"man termios" for more info.

Now calls to "getchar()" and friends won't be line buffered and won't block.

"man getchar" for more info.

There is a slightly simpler way to achieve both without the "fcntl" call too:

#include <unistd.h>
#include <termios.h>

// un-line buffer stdin and optionally set non-blocking
void set_stdin(const bool block /* false for non-blocking */)
{
const int fd = fileno(stdin);
termios flags;
if (tcgetattr(fd,&flags)<0) { ... /* handle error */}
flags.c_lflag &= ~ICANON; // set raw (unset canonical modes)
flags.c_cc[VMIN] = block; // i.e. min 1 char for blocking, 0 chars for non-blocking
flags.c_cc[VTIME] = 0; // block if waiting for char
if (tcsetattr(fd,TCSANOW,&flags)<0) { ... /* handle error */}
}

Of course you need to reset all control flags to get back to normal after.
any of these calls.

HTH,

--
Lionel B
Sep 27 '08 #9

P: n/a
On Sep 27, 9:41 am, Lionel B <m...@privacy.netwrote:
On Fri, 26 Sep 2008 17:48:06 -0700, puzzlecracker wrote:
On Sep 26, 5:55 pm, Lionel B <m...@privacy.netwrote:
On Fri, 26 Sep 2008 08:50:28 -0700, puzzlecracker wrote:
is it even possible
I don't believe it is in an OS-independent way. I don't
think C++ has a notion of non-blocking I/O at all - a read
failure is always simply treated as an "error".
Maybe have a look at the Boost.Iostreams library:
>http://www.boost.org/doc/libs/1_36_0...doc/index.html
and in particular section 3.6 (Asynchronous and
Non-Blocking I/O). But I get the impression it's not quite
there yet.
or/and there is a better alternative to accept input in a
nonblocking manner?
I'm not sure what you mean here.
What are you actually trying to do? I can tell you how to
put stdin into non-blocking mode on a POSIX (e.g. Linux)
terminal, if you're interested (and also how to make it non
line-buffered, which you probably want too in that case).
Sure, I am actually building apps on Linux, hence posix
works. Can't use boost. Please demonstrate it(please don't
flame me for OT)
I won't, but someone else possibly will ;)
Well, since he knows it's off topic, and he knows the group
where it would be on topic (and where he's really more likely to
get a complete answer): comp.unix.programmer.

It's fairly tricky. I wouldn't try it from std::cin, at least
not to begin with. Just set up fd 0 and read from it. (If
you're reading one character at a time, with no buffering,
istream and streambuf really don't buy you anything but
portability. Which he'll have lost anyway.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 27 '08 #10

P: n/a
In article <f1**********************************@a70g2000hsh. googlegroups.com>,
puzzlecracker <ir*********@gmail.comwrote:
>is it even possible or/and there is a better alternative to accept
input in a nonblocking manner?
I'd avoid the problem altogether:

I'd simply create a cin reader thread whose job would be to read input
safely from a blocking cin. It could also be charged with validating
this input if desirable.

I'd put a thread safe FIFO communication mechanism between the two
threads (e.g. mutex protected std::queue) and the main process thread
would peek if there is a message on the queue for it, if so, read and
process it, if not, continue with its other tasks.

To me, that sounds simpler than trying to turn cin as non-blocking.
plus anyway, non-blocking cin would think that there is data to be
read if only one character was present in the buffer but you may wish
to get input as complete words (lines?) and not interrupt normal
processing until a complete word is available. This would be trivial
to do with the input thread model but much more difficult with a
non-blocking cin or stdin.
Yannick
P.S.: Obviously, I'd use Boost Thread for that...
http://www.boost.org/doc/libs/1_36_0...ml/thread.html



Sep 29 '08 #11

P: n/a
On Mon, 29 Sep 2008 15:18:56 +0000, Yannick Tremblay wrote:
In article
<f1**********************************@a70g2000hsh. googlegroups.com>,
puzzlecracker <ir*********@gmail.comwrote:
>>is it even possible or/and there is a better alternative to accept input
in a nonblocking manner?

I'd avoid the problem altogether:

I'd simply create a cin reader thread whose job would be to read input
safely from a blocking cin. It could also be charged with validating
this input if desirable.

I'd put a thread safe FIFO communication mechanism between the two
threads (e.g. mutex protected std::queue) and the main process thread
would peek if there is a message on the queue for it, if so, read and
process it, if not, continue with its other tasks.

To me, that sounds simpler than trying to turn cin as non-blocking. plus
anyway, non-blocking cin would think that there is data to be read if
only one character was present in the buffer but you may wish to get
input as complete words (lines?) and not interrupt normal processing
until a complete word is available. This would be trivial to do with
the input thread model but much more difficult with a non-blocking cin
or stdin.
That sounds pretty complicated to me... but then I really don't know how
you'd make cin non-blocking (or non-line-buffered, for that matter), so I
don't know how complicated that would be.

But if you're prepared to forgo cin and use stdin, then (at least in
unix) it's pretty straightforward - including getting line-buffered
input in non-blocking mode. See e.g. my simple stdin control utilities
and demo:

ftp://ftp.informatics.sussex.ac.uk/p.../stdin_control

--
Lionel B
Sep 30 '08 #12

P: n/a
In article <gb**********@south.jnrs.ja.net>, Lionel B <me@privacy.netwrote:
>On Mon, 29 Sep 2008 15:18:56 +0000, Yannick Tremblay wrote:
>In article
<f1**********************************@a70g2000hsh .googlegroups.com>,
puzzlecracker <ir*********@gmail.comwrote:
>>>is it even possible or/and there is a better alternative to accept input
in a nonblocking manner?

I'd avoid the problem altogether:

I'd simply create a cin reader thread whose job would be to read input
safely from a blocking cin. It could also be charged with validating
this input if desirable.

I'd put a thread safe FIFO communication mechanism between the two
threads (e.g. mutex protected std::queue) and the main process thread
would peek if there is a message on the queue for it, if so, read and
process it, if not, continue with its other tasks.

To me, that sounds simpler than trying to turn cin as non-blocking. plus
anyway, non-blocking cin would think that there is data to be read if
only one character was present in the buffer but you may wish to get
input as complete words (lines?) and not interrupt normal processing
until a complete word is available. This would be trivial to do with
the input thread model but much more difficult with a non-blocking cin
or stdin.

That sounds pretty complicated to me... but then I really don't know how
you'd make cin non-blocking (or non-line-buffered, for that matter), so I
don't know how complicated that would be.
Depends. I am fairly confortable with threads. Using boost threads,
creating a thread in a sane way is a couple of lines, a thread-safe
queue is obviously something that I have sitting in that library ready
to be used, so really not as complicated as it may sound.

It also make a nice separation of task:
Main thread does the processing
User input thread manage user input, read it and validate it before
passing it to the main thread.

Both threads have very limited interaction which is a good idea with
threads.
Each threads is individually simpler than if it was trying to do both
task in one.
Each thread can be independently tested.
Pattern very easy to extend to input via other channels than cin.
>But if you're prepared to forgo cin and use stdin, then (at least in
unix) it's pretty straightforward - including getting line-buffered
input in non-blocking mode. See e.g. my simple stdin control utilities
and demo:

ftp://ftp.informatics.sussex.ac.uk/p.../stdin_control
I had a peek at it. It's a nice little wrapper over fcntl. It would
probably be the better choice for simple task like non-blocking
character input.

Yannick
Sep 30 '08 #13

This discussion thread is closed

Replies have been disabled for this discussion.