Telling an std::thread to kill/stop itself when a condition is met

alxcyl picture alxcyl · Sep 18, 2013 · Viewed 38.5k times · Source

Say I have a worker thread tWorker, which is initialized when Boss is constructed and tells it to do work(), until bRetired is true. An std::mutex, mtx, locks some data (vFiles) so that tWorker owns it when he's working on it.

How do I make tWorker "commit suicide" once bRetired becomes true? How would the mutex be destroyed when the thread stops execution?

I've read that std::thread objects cannot be interrupted in any way. Does letting the thread do nothing (or calling std::this_thread::yield()) provide the same effect as killing the thread?

class Boss {
private:
    std::thread tWorker;
    std::mutex mtx;
    bool bRetired;
    std::vector< std::string > vFiles;

    void work() {
        while ( bRetired == false ) {
            // Do your job!
            mtx.lock();
            // ... Do something about vFiles ...
            mtx.unlock();
        }

        // tWorker has retired, commit suicide
        // ** How? **

        // Does this suffice if I want to "kill" the thread?
        std::this_thread::yield(); 
    }

public:
    Boss() {
        bRetired = false;
        tWorker = std::thread( &Boss::work, this );

        // Have worker do its job independently
        // **Bonus Question** : Should this be tWorker.join() or tWorker.detach()?
        tWorker.detach();
    }

    retire() {
        bRetired = true;
    }
}

Notes

  • The worker thread cannot be started again once it is retired.
  • The worker thread works on the background without interrupting the main thread's execution.

Answer

Maxim Egorushkin picture Maxim Egorushkin · Sep 18, 2013

How do I make tWorker "commit suicide" once bRetired becomes true?

You let the control flow exit the thread function. That std::this_thread::yield() call in unnecessary.

How would the mutex be destroyed when the thread stops execution?

That mutex is a member of Boss class. It gets destroyed in the destructor of Boss when the object is getting destroyed.

I've read that std::thread objects cannot be interrupted in any way.

C++ API does not provide means to terminate an arbitrary thread. There has to be a way to tell a thread to terminate and then wait till it does, as you intend to do.

Does letting the thread do nothing (or calling std::this_thread::yield()) provide the same effect as killing the thread?

No.

There is a race condition on bRetired variable though. It either needs to be std::atomic<bool> or it should only be read and modified only when that mutex is locked.