0

I want to make a keyboard interrupt to exit a while loop. Instead of using _getchar() or cin inside the while loop, which wait for the user input, I want to find a way that allows for an optional keyboard interrupt: the loop should continue indefinitely until the user decides to stop it.

For this goal, creating threads could help, but I am very new into the topic. I implemented this in this example code. I use C++ Visual Studio 2019 in Windows.

#include <iostream>  // std::cout
#include <thread>    // std::thread

int exitWhile = 0;      
void interrupt()
{
    std::cin >> exitWhile;   // Get "exitWhile" from keyboard
}

int main()
{
    std::thread t(interrupt); // Spawn new thread

    while (exitWhile != 1)  // If keyboard input is "1", exit while loop
    {
       std::cout << "Inside while loop" << std::endl;
       t.join();               
    }


std::cout << "Exit while.\n";

return 0;
}

However, the while loop is executed one first time and then waits for the thread "t" to be finished because of the join() function. I would like to run the thread in parallel such that the global variable gets modified at any time, until which the while loop will keep repeating. Any ideas on how to implement this behavior?

  • Take a look at this: https://godbolt.org/z/nzxTMa. Note the `sleep_for` inside the loop to avoid very large output. – Benny K Jul 30 '20 at 10:37
  • @BennyK, your code snippet has a race condition. You have concurrent (read and write) to an object `exitWhile`. Wrapping it in a simple `std::atomic` would remove that race condition – WhiZTiM Jul 30 '20 at 10:50
  • @BennyK thank you. Using join() outside the loop does make it work. Why have you added another `sleep_for` inside the interrupt thread? – nicolas005 Jul 30 '20 at 11:41
  • @nicolas005 Just a test - because it's difficult to simulate user input in godbolt. – Benny K Jul 30 '20 at 12:15
  • @WhiZTiM - Yes, there's a race condition, but it does not really affect the functionality. You might perform one additional loop unnecessarily, but on the other hand, all operations might be slower, so the gain from `std::atomic` is questionable. – Benny K Jul 30 '20 at 12:17

1 Answers1

0

Dont join in the loop. If you manage to get your thread to change the variable in main(you will probably need to pass it a pointer to exitWhile, also look into atomic variables which are thread safe). Then you need to join after the while loop just to close the thread. Even if this did loop through once, it would fail on second loop as thread t has already been joined. so first check if thread is joinable, and then join it(after it has served its purpose, so outside the loop). And with threads that dont end normally(a socket thread perhaps) you need to also shut them down first since join doesent end the thread, just makes the code execute in the main thread again.

TineO
  • 1,023
  • 8
  • 24
  • I have implemented that and the thread is able to interrupt the while loop now. Unfortunately I still do no understand how to avoid console blocking, in case the user does NOT interrupt: the thread interrupt hangs there for ever. – nicolas005 Jul 30 '20 at 13:41