[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

How to make non-blocking call to cin?

puzzlecracker

9/26/2008 3:50:00 PM

is it even possible or/and there is a better alternative to accept
input in a nonblocking manner?
10 Answers

Victor Bazarov

9/26/2008 4:10:00 PM

0

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

James Kanze

9/26/2008 9:02:00 PM

0

On Sep 26, 6:09 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> 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:james.kanze@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

Victor Bazarov

9/26/2008 9:43:00 PM

0

James Kanze wrote:
> On Sep 26, 6:09 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>> 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

jt

9/26/2008 9:56:00 PM

0

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/libs/iostreams/doc/...

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

puzzlecracker

9/27/2008 12:48:00 AM

0

On Sep 26, 5:55 pm, Lionel B <m...@privacy.net> wrote:
> 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/libs/iostreams/doc/...
>
> 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

Ian Collins

9/27/2008 1:26:00 AM

0

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.

James Kanze

9/27/2008 6:44:00 AM

0

On Sep 27, 3:26 am, Ian Collins <ian-n...@hotmail.com> wrote:

[...]
> 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:james.kanze@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

jt

9/27/2008 7:41:00 AM

0

On Fri, 26 Sep 2008 17:48:06 -0700, puzzlecracker wrote:

> On Sep 26, 5:55 pm, Lionel B <m...@privacy.net> wrote:
>> 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/libs/iostreams/doc/...
>>
>> 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

James Kanze

9/27/2008 6:27:00 PM

0

On Sep 27, 9:41 am, Lionel B <m...@privacy.net> wrote:
> On Fri, 26 Sep 2008 17:48:06 -0700, puzzlecracker wrote:
> > On Sep 26, 5:55 pm, Lionel B <m...@privacy.net> wrote:
> >> 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/libs/iostreams/doc/...

> >> 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:james.kanze@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

ytrembla

9/29/2008 3:19:00 PM

0

In article <f1ea726e-49a0-440b-bad9-1c8ca1637b11@a70g2000hsh.googlegroups.com>,
puzzlecracker <ironsel2000@gmail.com> wrote:
>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/doc/html/t...