Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::thread - "terminate called without an active exception", don't want to 'join' it

As per This Question, I'm using a thread to terminate a function on user input. My code looks something like:

bool stopper = false;
thread stopThread(userStop, &stopper);      // start thread looking for user input
for(int i = 0; i < 1000; i++) {
    if(stopper) { break; }                  // break if desired
    // Do stuff
}
return 0;

where,

userStop(bool *st) {
    char chChar = getchar();
    if(chChar == '\n') {
        *st = true;
    }
}

When I run this, I get the error terminate called without an active exception. Based on these questions: thread terminate called without an active exception, C++ terminate called without an active exception; it looks like its because I'm not 'join'ing the thread again.

The problem is, I don't want to 'join' the thread -- because then the user will need to provide input for userStop()to terminate, but I only want the user to provide input if the for-loop is to be broken (which it isn't necessarily).

Thanks!

like image 765
DilithiumMatrix Avatar asked Dec 22 '12 02:12

DilithiumMatrix


People also ask

How do I terminate a STD thread?

You could call std::terminate() from any thread and the thread you're referring to will forcefully end. You could arrange for ~thread() to be executed on the object of the target thread, without a intervening join() nor detach() on that object.

How do you wait until all threads are finished C++?

2.1. 2. Waiting for a thread to complete. If you need to wait for a thread to complete, you can do this by calling join() on the associated std::thread instance.

What does detaching a thread do?

thread::detachSeparates the thread of execution from the thread object, allowing execution to continue independently. Any allocated resources will be freed once the thread exits. After calling detach *this no longer owns any thread.

How do you delete a thread in C++?

Check the checkbox of the thread you want to delete. Click on the Delete button.


3 Answers

The trouble you are encountering is a result of the stopThread going out of scope on the stack. The C++ standard has the following to say about this:

30.3.1.3 thread destructor [thread.thread.destr]

~thread();

If joinable() then terminate(), otherwise no effects. [ Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. — end note ]

What this means is that you should not let threads go out of scope without first calling either join() or detach().

The way you describe it, you want the thread to go out of scope without joining so it will continue to run as your application runs. That requires a call to detach(). From there, I can only offer a little wisdom...

  • That thread is now completely responsible for its own lifetime. If it doesn't return on its own, it will run forever (until the process terminates).

  • You are getting user input, presumably from something like cin or getch(). If these are accessed from multiple threads, you do not have much assurance that there are not race conditions in their library implementations. Tread lightly.

like image 187
Sean Cline Avatar answered Oct 22 '22 16:10

Sean Cline


In your standard input thread, you'll want to asynchronously read from input. And wake up on both a demand to stop reading, and new input.

Terminating a thread without joining is not a reasonable thing to do. So what you need to be able to do is say "yo thread, finish up right now", then be able to expect that the join will finish promptly. This can even be via a two-step handshake ("yo thread, finish up", followed by "ok ok, I managed to clean up, join me now") in some cases.

Note that your loop to 1000 looks really ridiculous: user input timeouts should generally be based on actual time passing, or some other event occurring that makes the user input non-useful.

like image 43
Yakk - Adam Nevraumont Avatar answered Oct 22 '22 14:10

Yakk - Adam Nevraumont


Terminating a thread is a bad idea -- you should make your thread exit gracefully. If you did terminate the thread, you'd end up causing code in the getch() function to end unexpectedly. What if that code was in the middle of managing a data structure, allocating or freeing memory, or doing some other work that had to execute until completion? You'd end up leaving something in an invalid state, and you'd eventually crash when that invalid state was exercised.

like image 1
MikeB Avatar answered Oct 22 '22 15:10

MikeB