grunk
grunk

Reputation: 14948

Interrupt a detached boost::thread

I have a class with a thread running like this :

class MyClass
{
    public:
        void Start();
        void Stop();
        void Run();
    private:
        boost::thread mThread;
        bool mThreadShouldRun;
}

void MyClass::Start()
{
    mThreadShouldRun = true;
    mThread = boost::thread(&MyClass::Run, this);
}

void MyClass::Stop()
{
    mThreadShouldRun = false;
    mThread.interrupt();
}

void MyClass::Run()
{
    while(mThreadShouldRun)
    {
        //DO Something
        try {
            boost::this_thread::sleep_for(boost::chrono::seconds(15));
        } catch(boost::thread_interrupted interrupt) {
            break;
        }
    }
}

This code is doing what i'm expecting : Launching a background thread and stopping it on demand.

But according to the answer of this question join() or detach() should always be called. join() is not what i need in my case , so i go for detach() :

void MyClass::Start()
{
    mThreadShouldRun = true;
    mThread = boost::thread(&MyClass::Run, this);
    mThread.detach();
}

The thread still running as expected but mThread become Not-a-Thread and i can no longer interrupt it in the Stop() method because mThread no long reference the thread after the call to detach().

Should i really call detach() ? And if yes how to interrupt() the detached thread ?

Upvotes: 0

Views: 1275

Answers (1)

Netwave
Netwave

Reputation: 42786

Just interrupt the thread and then wait for it to return:

#include <mutex>
class MyClass
{
    public:
        void Start();
        void Stop();
        void Run();
    private:
        boost::thread mThread;
        bool          mThreadShouldRun;
}

void MyClass::Start()
{
    mThreadShouldRun = true; 
    mThread = boost::thread(&MyClass::Run, this);
}

void MyClass::Stop()
{
    mThreadShouldRun = false;// dont really needed anymore but may be ok
    mThread.interrupt();
    mThread.join();
}

void MyClass::Run()
{
    while(mThreadShouldRun)
    {
        //DO Something
        try {
            boost::this_thread::sleep_for(boost::chrono::seconds(15));
        } catch(boost::thread_interrupted interrupt) {
            break;
        }
    }
}

Upvotes: 2

Related Questions