Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I put a thread in a C++ smart pointer?

I want to create a C++ class with a thread doing some work once a minute.

First, may I define a thread as a variable member?

class my_class
{
public:
    my_class()
        : my_thread_(task, this)
    {
    }

    ~my_class()
    {
        done_ = true;
    }

    void run()
    {
        while(!done_)
        {
            ...do work in the thread...
        }
    }

private:
    static task(my_class * ptr)
    {
        ptr->run();
    }

    std::thread          my_thread_;
    std::atomic<bool>    done_ = false;
};

Second, may I instead use a smart pointer with the thread in it?

class my_class
{
public:
    ~my_class()
    {
        done_ = true;
    }

    void init()
    {
        my_thread_.reset(new std::thread(task, this));
    }

    void run()
    {
        while(!done_)
        {
            ...do work in the thread...
        }
    }

private:
    static task(my_class * ptr)
    {
        ptr->run();
    }

    std::unique_ptr<std::thread>    my_thread_;
    std::atomic<bool>               done_ = false;
};

It seems to me that I need to join with the child thread before it can be destroyed, but I am wondering whether the destructor of std::thread knows to do that safely.

like image 506
Alexis Wilke Avatar asked Jun 05 '16 20:06

Alexis Wilke


1 Answers

You can put std::threads where ever you want, they are not special. Destroying thread handles is problematic. You can implicitly detach, implicitly kill or implicitly join and every option is bad. std::~thread (usually) just kills the whole program. To prevent that join or detach it.
Since you seem to want to implicitly join you may want to use std::async (probably with the std::launch::async policy) to launch your threads. It returns an std::future who's destructor implicitly joins.

like image 148
nwp Avatar answered Sep 27 '22 18:09

nwp