I\'ve encountered a specific problem with my implementation and can\'t find a solution for it.
I have a two-part application. One part is a Java swing GUI. The second pa
After trying for a long time to implement non-blocking input from cin, I'm pretty sure it's impossible to getting it to work consistently.
My current solution is to put the blocking cin into it's own tiny thread and let it do it's thing.
I've simplified my implementation a little bit for this example, as you need a thread safe storage system of some kind.
#include
#include
#include
#include
// Super simple thread safe storage
std::queue Database;
std::mutex Padlock;
void PushLine(std::string Line) {
std::unique_lock Lock(Padlock); (void)Lock;
Database.push(Line);
}
bool IsLineAvailable(void) {
std::unique_lock Lock(Padlock); (void)Lock;
return !Database.empty();
}
std::string PopLine(void) {
std::unique_lock Lock(Padlock); (void)Lock;
std::string Line(std::move(Database.front()));
Database.pop();
return Line;
}
// Main function with "non-blocking" input from cin
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
std::thread InputThread = std::thread([](){
do {
// Ensure the input is as clean as possible
if (std::cin.rdbuf()->in_avail()) {
std::cin.ignore(std::cin.rdbuf()->in_avail());
}
std::cin.clear();
// Get a line, cin will block here.
std::string Line;
std::getline(std::cin, Line);
// If the line is not empty attempt to store it.
if (!Line.empty()) {
PushLine(Line);
}
} while (1);
});
// Detach from the thread, it will never end.
InputThread.detach();
// A job to do.
unsigned int Counter = 0;
// Run your program.
bool Running = true;
while(Running) {
// Perform a job, in this case counting.
Counter++;
// Check for available input
if (IsLineAvailable()) {
// If there is input available, first get it
std::string Line = PopLine();
// Echo it to the terminal
std::cout << "Command: " << Line << std::endl;
// Perform actions based on the command
if (Line == "quit") {
Running = false;
}
else if (Line == "count") {
std::cout << " Count: " << Counter << std::endl;
}
}
// Sleep for a while
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
// Done.
return 0;
}