struct Test {
bool active{true};
void threadedUpdate() {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if(!active) // crashes here after Test instance is destroyed
return;
}
Test() {
std::thread([this]{ while(true) threadedUpdate(); }).detach();
}
~Test() {
// somehow stop the detached thread?
}
};
When an instance of Test
is initialized, it spawns and detaches an std::thread
which runs in background. When the same instance is destroyed, the previously mentioned thread tries to access the active
member, which was destroyed along with the instance, causing a crash (and an AddressSanitizer backtrace).
Is there a way to stop the detached thread on ~Test()
?
The design is bad. How should a thread running in background until the caller is destroyed be spawned/handled correctly?
Detaching ThreadsSeparates the thread of execution from the thread object, allowing execution to continue independently. Any allocated resources will be freed once the thread exits.
In C++, once the thread is detached or uses the detach() function, then we cannot stop such threads, and still, if there is a need for stopping such threads, then only one way is to return the thread from the initial thread function by instantiating it in main() function, adding the Boolean value but before exiting ...
When a thread is created, one of its attributes defines whether it is joinable or detached. Only threads that are created as joinable can be joined. If a thread is created as detached, it can never be joined.
If you don't join these threads, you might end up using more resources than there are concurrent tasks, making it harder to measure the load. To be clear, if you don't call join , the thread will complete at some point anyway, it won't leak or anything.
Make the thread a member of the class, and instead of detaching it in the constructor, join it in the destructor. To stop the thread from looping, you can have a boolean inside the class that signals whether the thread should continue running or not (std::atomic<bool> update
).
The thread could be executing this: [this] { while (update) threadUpdate(); }
.
In the destructor of your class, do update = false
, and call thread.join()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With