2

I have a simple c++ thread that waits for user to prematurely kill the program by pressing 'q' then runs the kill sequence. My problem is, the user does not always press 'q' and usually the programs runs its course.

However I cannot find a good way to end the thread in cases where user does not press "q". I've been just returning from main with the thread open and letting the program crash. While this works, I am hoping there is a more elegant solution out there. I've also tried to detach the thread before returning from main, and while this does not cause a crash, It's behavior is undefined. Some say the thread will run indefinitely.

void manualKill(killEventClass &killEvent)
{
    cin.ignore(1000, 'q');
    killEvent.set();
} 

int main()
{
    thread manualKillThread(manualKill, ref(killEventClass));
    //do stuff
    manualKillThread.detach();
    return 0;
}

Edit:

It appears that there is no way to do this with the standard C++ library, I would have to find some OS specific approach that captures keys.

Honestly detaching the thread, while it's not ideal, it is portable, and probably the lesser evil. Since my program is ending regardless.

Thank you for all your answers.

Marc
  • 21
  • 2
  • I don't think there is portable way. The boost::thread had terminate, but no such thing in std::thread. – Öö Tiib Oct 05 '22 at 14:35
  • I would try to use std::async and future::wait_for instead of std::thread. – Öö Tiib Oct 05 '22 at 14:40
  • 2
    Terminating threads usually is not the way. And to be honest with a blocking key get I think most solutions for interrupting would not work well. – Pepijn Kramer Oct 05 '22 at 14:40
  • @ÖöTiib While I prefer std::async as well, that's not going to solve things. The thread launched/used by async with std::cin will still block. – Pepijn Kramer Oct 05 '22 at 14:41
  • Within standard C++ I/O there is no way, since standard streams either return immediately (e.g. if the stream is in an error state) or wait for input (which may or may not result in the stream entering an error state). To do what you want, you'll need ways to wait on (or, maybe, poll for) *keyboard* input (which is not what `cin` does). The means of doing that tend to be either system (e.g. OS) specific, or rely facilities (e.g. third party libraries or APIs supported by some particular operating systems) that are not part of standard C++. – Peter Oct 05 '22 at 14:41
  • Related : [capture-characters-from-standard-input-without-waiting-for-enter-to-be-pressed](https://stackoverflow.com/questions/421860/capture-characters-from-standard-input-without-waiting-for-enter-to-be-pressed) – Pepijn Kramer Oct 05 '22 at 14:42
  • You could try just `fclose(stdin)` or similar, but since I think the exact result is going to be platform-specific anyway, you might as well pick a platform and use its facilities directly. – Useless Oct 05 '22 at 14:55
  • 2
    I strongly urge you to avoid `detach`, because it requires great care to coordinate exit correctly. Such care is not present in the code given. – Eljay Oct 05 '22 at 16:15
  • When dealing with multi-threadding, typically user interactions should be done only in the main thread, and business logic can/should be done in worker threads. Not the other way around. – Remy Lebeau Oct 05 '22 at 20:14

0 Answers0