Asynchronous console input
I personally would just use platform dependent code. Create a function that wraps in_avail() and if it returns 0 then calls the appropriate function.
Quote:Original post by SiCraneGuess I will have to learn how to put Window's command prompt into non-blocking mode - plus it turns out the BSD and Linux termios structures are incompatible [wink]
I personally would just use platform dependent code. Create a function that wraps in_avail() and if it returns 0 then calls the appropriate function.
You can't, not really. The console doesn't participate in true async operations like other files/streams, so you have to jury rig something yourself. One option would be to WaitForSingleObject on the console input, with a timeout period and poll the thread's exit condition if the timeout expires. When there is data available, you'll have to peek at the console's input queue to check whether it contains keyboard input, because mouse movements and window activity will also satisfy the wait in default mode.
This might come in handy. The check for keyboard input starts on line 112 and, in your case, hConIn would be the result of GetStdHandle(STD_INPUT_HANDLE). It is pure Win32 but there's nothing stopping you using std::cin once you know there's input available.
This might come in handy. The check for keyboard input starts on line 112 and, in your case, hConIn would be the result of GetStdHandle(STD_INPUT_HANDLE). It is pure Win32 but there's nothing stopping you using std::cin once you know there's input available.
Quote:Original post by adeyblueYuk!
You can't, not really. The console doesn't participate in true async operations like other files/streams, so you have to jury rig something yourself...
This might come in handy.
The more I search, the more I think that the threading solution is the simplest/best. It is only a few lines of code, works on any platform with thread support, and the input thread will spend its entire lifetime blocked on std::getline(), so it won't consume a noticeable number of CPU cycles.
It looks like this:
#include <boost/thread.hpp>#include "LocklessQueue.h"#include <iostream>#include <string>LocklessQueue< std::string > commands(16);struct InputServer{ void operator () () { while (1) { std::string command; std::getline(std::cin, command); while (!commands.push(command)) ; // spin till the main thread consumes a queue entry } }};int main() { InputServer input; boost::thread inputThread(input); std::cout << "server launched.\n>> " << std::flush; while (1) { std::string command; if (commands.pop(command)) { if (command == "status") std::cout << "server running...\n>> " << std::flush; else if (command == "quit") { std::cout << "bye!" << std::endl; break; } else { std::cout << "unrecognised command.\n>> " << std::flush; } } } exit(0);}
I don't see why threading is such a bad idea. To me it seems like the perfect place to use it. You need to do two things at once: output text, and gather input. Threads allow you to do two things at once (more or less). Therefore, use threads. Can't argue with that logic [grin].
It may be a bit messy that you have to forcibly kill the blocking thread but if it works it works. Maybe you could quit when the user types "quit" or something, and exit the input thread neatly when that happens. Although the user could also quit by closing the console window.
It may be a bit messy that you have to forcibly kill the blocking thread but if it works it works. Maybe you could quit when the user types "quit" or something, and exit the input thread neatly when that happens. Although the user could also quit by closing the console window.
Quote:Original post by XTAL256Yeah, I am probably being overly pedantic. The input thread doesn't carry any heavy resources (just its own stack space), and the OS will cleanup everything as soon as the application exits, so forcibly killing it should be perfectly safe.
It may be a bit messy that you have to forcibly kill the blocking thread but if it works it works.
Just use the polling mechanisms of your OS.
On windows, WaitForSingleObject.
On linux/mac/unix, select.
On windows, WaitForSingleObject.
On linux/mac/unix, select.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement