Search code examples
c++multithreadingc++11detachstdthread

std::thread::detach causes crash after original caller is destroyed


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?


Solution

  • 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()