C++ console input blocks so i can't kill thread

為{幸葍}努か 提交于 2019-12-07 06:58:00

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!