Jump to content
  • Advertisement
Sign in to follow this  
swiftcoder

Asynchronous console input

This topic is 3316 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am trying to find a way to perform asynchronous input on the command line, as for a chat client (which may receive messages whilst awaiting user input). This is for C++ (though a Python method wouldn't hurt), and the solution needs to be cross-platform. Since I don't know of any way to make std::cin non-blocking, the obvious method seemed to spawn another thread, which reads a line from std::cin in a loop, and communicates it to the server thread over a loackless-queue. This works pretty well, except when it comes to exiting the program - my threading library (boost::thread) provides no way to forcibly kill another thread, and the input thread is blocked on std::cin, so can't receive a message to quit. A call to exit(0) solves this, but it doesn't seem to be the cleanest of solutions. So, my question to you: is there anyway to make std::cin non-blocking, or to test for available data before calling std::getline()?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by SiCrane
Did you try checking std::cin.rdbuf()->in_avail() ?
As I understand it, streambuf.in_avail() only returns the number of characters remaining after a read operation underflows - and the only way to generate an underflow is a blocking read call.

Share this post


Link to post
Share on other sites
If the streambuf input buffer is empty, in_avail() calls showmanyc(), which is used to check if a subsequent call to underflow() will succeed or not.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
If the streambuf input buffer is empty, in_avail() calls showmanyc(), which is used to check if a subsequent call to underflow() will succeed or not.
Nevertheless, it doesn't work - calling in_avail() in a loop always returns 0, no matter how many characters and lines I type at the command prompt. Perhaps the buffering is interfering?

Share this post


Link to post
Share on other sites
No, it's probably because your standard library implementation just doesn't probe stream for input when showmanyc() is called. A lot of the C++ standard is more suggestive than proscriptive.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
No, it's probably because your standard library implementation just doesn't probe stream for input when showmanyc() is called. A lot of the C++ standard is more suggestive than proscriptive.
Right, makes sense. Is multi-threading the only other solution? I mean, multi-threading works, but it seems a little bit like overkill.

Share this post


Link to post
Share on other sites
AFAIK in_avail() and showmanyc() are the only ways to check for input status without a blocking call in standard C++. However, there are other portable alternatives. For example, a curses library like pdcurses can be used to detect if there's keyboard input, though it may not play happily with any buffering done by std::cin.

Share this post


Link to post
Share on other sites
I am sure there are cross platform libraries that can do this. I haven't used it, but something like curses probably has this functionality without worrying about threading. There might be smaller libraries that let you do the same thing too.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
However, there are other portable alternatives. For example, a curses library like pdcurses can be used to detect if there's keyboard input, though it may not play happily with any buffering done by std::cin.
Quote:
Original post by rip-off
I am sure there are cross platform libraries that can do this. I haven't used it, but something like curses probably has this functionality without worrying about threading. There might be smaller libraries that let you do the same thing too.
Ja, curses and friends do expose this functionality. They appear to do this in a fairly naive way, by completely disable buffering for stdin, and emulating line-buffering.

I am not entirely happy with that approach, as curses is a fairly heavy (and unfortunately antiquated) dependency. All of the newer (and lighter) curses replacements seem to depend on curses for this functionality.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!