How to define a non blocking input in C++

0


I'm making a multithread application in C++. In particular, a secondary thread is involved in input operations, the problem is that std::cin is a blocking instruction and this create some problems in the execution flow of my program. If main thread end its execution, secondary thread should do the same, but it's blocked on std::cin, so user has to insert something to let the program to end. It's possible to overcome this problem?

Here's the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <future>
#include <string>
#include <chrono>
#include <thread>
#include <atomic>

std::atomic<bool> interrupt(false);

std::string get_input(){

  std::cout << "Insert a new command: ";
  std::string cmd;
  std::cin >> cmd;
  return cmd;

  }

void kill_main_thread(){

  std::this_thread::sleep_for(std::chrono::milliseconds(5000));
  interrupt = true;

  }

int main() {

  std::thread new_thread (kill_main_thread);     // spawn new thread that calls foo()


  while(1) {

      if ( interrupt ) {
          return 0;
      }

      std::future<std::string> fut = std::async(get_input);
      if ( fut.wait_for(std::chrono::seconds(500)) == std::future_status::timeout ){

          std::string cmd = fut.get();

            
           if ( cmd == "close") std::cout << "close command\n";
            else if ( cmd == "open") std::cout << "open command\n";
            else  std::cout << "not recognized command\n";

      }

  }
return 0;
}
  


So basically I found three possible solutions for my purpose:

1.) Is it possible to realize a non blocking std::cin?
2.) Is there any interrupt or kill signal that will stop execution of the secondary thread?
3.) Is it possible to virtualize in some way std::cin? In kill_main_thread() function I tried it by using this instruction:

1
2
3
4
5
6
7
    void kill_main_thread(){
      ...
      ...
      std::istringstream iss;
      std::cin.rdbuf(iss);

     }

But secondary thread is still blocked on std::cin.

I also tried by using getch() function of conio.h library to create a non blocking input function to replace std::cin, but first of all my application should preferly work on different OS and secondary it create a bit of problem with managing of console because I need to change every std::cout of my program in this way.
In case I can manage the problem in a different way depending by OS, my application should work on Windows and Linux

Last edited on
Standard streams are inherently blocking. If you need non-blocking console input then you should use ncurses or PDcurses.
Topic archived. No new replies allowed.