问题
My program has many different threads handling different things, and one of them deals with user input.
The other threads don't have much in the way of blocking calls, and those that do block are network based so will be interrupted or return gracefully when the socket is shut down.
However the user thread has calls to std::cin
in order to grab the user input. The effect this has is while all the other threads are dead the user thread is still blocking on user input, and will only die the next time input is given.
Is there any way for me to check if there is any user input to grab before blocking?
I understand cin.peek()
exists but from my experience, it blocks if there is nothing to read in. Assuming I'm using it correctly
My code is basically an infinite loop that stops when another thread switches the condition variable:
void doLoop()
{
while (running) //running is shared between all threads and all others die quickly when it is false. It's set to true before the threads are started
{
string input = "";
getline(cin, input);
//Handle Input
}
}
I'm on windows, using VS2013, and cannot use external libraries. I'm using windows.h and std throughout.
回答1:
What you could do is using futures to allow the user to input something with a time limit. You can then insert this code into your main loop
#include <iostream> // std::cout
#include <future> // std::async, std::future
#include <chrono> // std::chrono::milliseconds
#include <string>
using namespace std;
bool myAsyncGetline(string & result)
{
std::cout<<"Enter something within the time limit"<<endl;
getline(cin,result);
return true;
}
int main()
{
// call function asynchronously:
string res;
std::future<bool> fut = std::async (myAsyncGetline,res);
std::chrono::seconds span (20);
if (fut.wait_for(span)==std::future_status::timeout)
std::cout << "Too Late!";
else
cout<<"You entered "<<res<<" "<< endl;
return 0;
}
This is available in VS2012 so you should be able to reproduce it.
The output is "Tool Late!" if getline is still working after the timeout (20s), otherwise it outputs the result.
I think that it is simpler than messing around with killing thread as the function stop by itself if the time limit is hit. Tell me if you need help integrating it into your existing code I can assist.
回答2:
I believe that the C++ Standard does not offer a way of checking the standard input without blocking. Since you are willing to use platform specific functions, 'kbhit()' might suit your needs but it has been deprecated in Windows. An alternative is offered, _kbhit()
. Of course this is not portable to other platforms.
This is the link to MSDN: _kbhit
来源:https://stackoverflow.com/questions/27710672/c-console-input-blocks-so-i-cant-kill-thread