How to make non-blocking call to cin?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • puzzlecracker

    How to make non-blocking call to cin?

    is it even possible or/and there is a better alternative to accept
    input in a nonblocking manner?
  • Victor Bazarov

    #2
    Re: How to make non-blocking call to cin?

    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

    Comment

    • James Kanze

      #3
      Re: How to make non-blocking call to cin?

      On Sep 26, 6:09 pm, Victor Bazarov <v.Abaza...@com Acast.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:james.kan ze@gmail.com
      Conseils en informatique orientée objet/
      Beratung in objektorientier ter Datenverarbeitu ng
      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

      Comment

      • Victor Bazarov

        #4
        Re: How to make non-blocking call to cin?

        James Kanze wrote:
        On Sep 26, 6:09 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
        >puzzlecracke r 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

        Comment

        • Lionel B

          #5
          Re: How to make non-blocking call to cin?

          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:



          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

          Comment

          • puzzlecracker

            #6
            Re: How to make non-blocking call to cin?

            On Sep 26, 5:55 pm, Lionel B <m...@privacy.n etwrote:
            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:
            >

            >
            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

            Comment

            • Ian Collins

              #7
              Re: How to make non-blocking call to cin?

              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.

              Comment

              • James Kanze

                #8
                Re: How to make non-blocking call to cin?

                On Sep 27, 3:26 am, Ian Collins <ian-n...@hotmail.co mwrote:

                [...]
                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::readso me.

                --
                James Kanze (GABI Software) email:james.kan ze@gmail.com
                Conseils en informatique orientée objet/
                Beratung in objektorientier ter Datenverarbeitu ng
                9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                Comment

                • Lionel B

                  #9
                  Re: How to make non-blocking call to cin?

                  On Fri, 26 Sep 2008 17:48:06 -0700, puzzlecracker wrote:
                  On Sep 26, 5:55 pm, Lionel B <m...@privacy.n etwrote:
                  >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_GETF L);
                  if (fcflags<0) { ... /* handle error */}
                  if (fcntl(fd,F_SET FL,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,T CSANOW,&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,T CSANOW,&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

                  Comment

                  • James Kanze

                    #10
                    Re: How to make non-blocking call to cin?

                    On Sep 27, 9:41 am, Lionel B <m...@privacy.n etwrote:
                    On Fri, 26 Sep 2008 17:48:06 -0700, puzzlecracker wrote:
                    On Sep 26, 5:55 pm, Lionel B <m...@privacy.n etwrote:
                    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:
                    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.progr ammer.

                    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.kan ze@gmail.com
                    Conseils en informatique orientée objet/
                    Beratung in objektorientier ter Datenverarbeitu ng
                    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                    Comment

                    • Yannick Tremblay

                      #11
                      Re: How to make non-blocking call to cin?

                      In article <f1ea726e-49a0-440b-bad9-1c8ca1637b11@a7 0g2000hsh.googl egroups.com>,
                      puzzlecracker <ironsel2000@gm ail.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...








                      Comment

                      • Lionel B

                        #12
                        Re: How to make non-blocking call to cin?

                        On Mon, 29 Sep 2008 15:18:56 +0000, Yannick Tremblay wrote:
                        In article
                        <f1ea726e-49a0-440b-bad9-1c8ca1637b11@a7 0g2000hsh.googl egroups.com>,
                        puzzlecracker <ironsel2000@gm ail.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

                        Comment

                        • Yannick Tremblay

                          #13
                          Re: How to make non-blocking call to cin?

                          In article <gbssvu$dp7$2@s outh.jnrs.ja.ne t>, Lionel B <me@privacy.net wrote:
                          >On Mon, 29 Sep 2008 15:18:56 +0000, Yannick Tremblay wrote:
                          >
                          >In article
                          ><f1ea726e-49a0-440b-bad9-1c8ca1637b11@a7 0g2000hsh.googl egroups.com>,
                          >puzzlecracke r <ironsel2000@gm ail.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

                          Comment

                          Working...