I have a class that starts another thread that accesses some of its data at constant intervals. This means I have two threads that access the same data (the original thread and the newly created thread). This introduces the need for a mutex. All goes well until the destructor of the class is called (at the end of the program) and the memory locations are no longer valid. At this point the new thread attempts to access the data and gets an access violation error (obviously).
What I would like to do is stop the thread in the destructor, or have the thread stop once it "notices" that the class instance has been destroyed.
Here is the simplified thread code (typedefs used for brevity):
void myClass::StartThread() {
auto threadFunc = [&, this]() {
while (true) {
time_point now = steady_clock::now();
if (chro::duration_cast<chro::milliseconds>(now - this->m_lastSeedTime).count() > INTERVAL) {
std::lock_guard<std::mutex> lockGuard(this->m_mut);
this->m_lastSeedTime = now;
this->accessData();
}
}
};
std::thread thread(threadFunc);
thread.detach();
of course if I am just mishandling this in some obvious way, please let me know as well.
If you want a thread to die, you should ask it to exit. It's the only reliable way to do it cleanly.
Just change
while (true)
to
while(this->keepRunning)
and synchronize it appropriately. Either don't detach the thread (so the destructor can join it) or add some way for the thread to indicate that it has exited (so the destructor can wait for it).
Oh, and instead of spinning, the thread should probably sleep. In that case, if you don't want the destructor to also block, you need some way to interrupt the sleep: using a timed wait on a condition variable for your sleep makes this easy.