std::thread - terminate called without an active exception, don't want to 'join' it
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
orgetch()
. 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.
C++ terminate called without an active exception
When a thread object goes out of scope and it is in joinable state, the program is terminated. The Standard Committee had two other options for the destructor of a joinable thread. It could quietly join -- but join might never return if the thread is stuck. Or it could detach the thread (a detached thread is not joinable). However, detached threads are very tricky, since they might survive till the end of the program and mess up the release of resources. So if you don't want to terminate your program, make sure you join (or detach) every thread.
thread terminate called without an active exception
You need locks around data
to protect against concurrent access to the same data structure from multiple threads.
wxWidgets - terminate called without an active exception (using std::thread)
Problem is here:
std::thread reader([this]() {
// thread code
});
reader_thread = &reader;
reader
will be destroyed after OnInit
function ends (and terminate will be called, since thread
is joinable). You should use smart-pointer in class in this case, or create reader_thread
using new
, or simply save thread in object and assign it to your reader_thread
(reader_thread should be object, not pointer) via move.
1) reader_thread = std::make_shared<std::thread>([this]() {});
2) reader_thread = new std::thread([this]() {});
3)
std::thread reader([this](){});
reader_thread = std::move(reader);
C++ Thread: terminate called without an active exception
Your code that creates the thread creates a stack variable that is immediately destroyed. You need to change this:
if(!isRepeatAllowed)
{
std::thread newThread(getUniqueInteger, arr, i, &newVal);
threadArr.push_back( &newThread);
}
to this:
if(!isRepeatAllowed)
{
std::thread* newThread = new std::thread(getUniqueInteger, arr, i, &newVal);
threadArr.push_back( newThread);
}
Then uncomment your delete line later on.
C++: Terminate called without an active exception (GCC)
On Linux (as on most OSes) exceptions are a language-agnostic feature, and pthread cancellation is implemented using language-agnostic exceptions (See e.g. Cancellation and C++ Exceptions).
When a pthread cancellation is delivered to a thread (using a signal, but you don't need to know that) the unwind machinery invokes all the installed personalities so that they can perform language-specific cleanup prior to the thread exiting. (This is pretty cool; it means that as in the above article you can insert a catch block for abi::__forced_unwind
to detect - though not to prevent - a thread cancellation.)
The problem is that an asynchronous cancellation can occur at any instruction, and the C++ exception tables generated by g++ only handle exceptions occurring at instructions known to be capable of generating exceptions (i.e. but not only calls to exception-throwing functions). If an exception is generated at a point not covered by the C++ tables, the C++ personality panics and terminates the process (hence "terminate called without an active exception").
The reason this is influenced by optimization is that the C++ personality is installed lazily, but with higher optimization levels the compiler might decide to preemptively install the C++ personality. You can guarantee the crash even at lower optimization levels by exercising the C++ exception machinery e.g. with try { throw 0; } catch (int) {}
.
The simplest fix is to ensure that the C++ personality is not installed in the thread you want to asynchronous cancel. You can ensure this by compiling the thread function as C and not calling any C++ functions from it.
A more hacky and highly unsupported solution is to ensure that all the asynchronous cancellation points (that is, all the instructions where the cancelled thread could be when the asynchronous cancellation is received) are in fact covered by the C++ unwind tables. Firstly you need to compile with -fnon-call-exceptions
; secondly you have to ensure that every instruction that could be an asynchronous cancellation point is between two points known to be synchronous cancellation points, e.g. pthread_testcancel
:
static void* busy(void*)
{
int oldstate ;
auto result = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&oldstate) ;
if (result != 0)
#ifdef NOEXCEPT
{ std::cerr << "pthread_setcanceltype" << std::endl ; abort() ; }
#else
throw std::runtime_error("pthread_setcanceltype") ;
#endif
pthread_testcancel();
for (unsigned i = 1; ; ++i)
if (i == 0)
pthread_testcancel();
return nullptr ;
}
Related Topics
Under What Circumstances Is It Advantageous to Give an Implementation of a Pure Virtual Function
What Does ## in a #Define Mean
Initialising Reference in Constructor C++
How to Append to a File with Fstream Fstream::App Flag Seems Not to Work
Casting to Void* and Back to Original_Data_Type*
Copy Constructor of Derived Qt Class
Are Destructors Run When Calling Exit()
Const Member and Assignment Operator. How to Avoid the Undefined Behavior
Windows Named Pipe Support in Linux
Use Static_Assert to Check Types Passed to MACro
After Sending a Lot, My Send() Call Causes My Program to Stall Completely. How Is This Possible
Why Is Std::Move Not [[Nodiscard]] in C++20
Cmake Error: "Add_Subdirectory Not Given a Binary Directory"
Linux, Need Accurate Program Timing. Scheduler Wake Up Program