std::thread() and std::ref() and PIMPL: C++11 Thread Semantics

196 views Asked by At

Below I have provided pseudo code for a situation I am encountering. I have two resources one that needs to be created on one thread and another that has to be created on the main thread. However, the first resource, ResourceA has to be recreated after ResourceB has been created, but ResourceA must be "primed" before ResourceB can be created (if you are interested in more details ask in the comments section.)

My exact questions are:

  1. Provided ResourceA and ResourceB are owned by a member pointer to a struct which will be modified on two separate threads. Do I have to use std::ref when passing the non-copyable parent object to a std::thread.
  2. If I do what is the differences in semantics between the two use cases (passing this as a pointer or using std::ref()?
  3. Since ResourceA has to be recreated after ResourceB and ResourceB is created on the second thread, will ResourceA on the main thread see the changes made to ResourceB if I don't use std::ref()?

The class in question would be defined as:

class Foo : public non_copyable // You can still move
{
private:
    struct FooImpl;
    FooImpl *m_foo;
    void Run();

public:
    Foo();
    ~Foo();
    bool Init();
};

Inside of Foo.cpp we have the following definition:

struct Foo::FooImpl
{
    ResourceA ra;
    ResourceB rb;
};

Foo::Foo() :
    m_foo(new FooImpl())
{}

Foo::~Foo()
{
    delete m_foo;
}

void Foo::Run()
{
    [Create Resource B in an advanced state needed to recreate A]

    [Notify condition on main thread so Resource B can be recreated]

    [Conditionally wait for A to be recreated on main thread]

    [Do stuff with B and this]
}    

bool Foo::Init()
{
    [Create Resource A in Preparation for Resource B this must be done on this thread]

    std::thread t(std::bind(&Foo::Run, this)); // Note here I am not passing 
                                               // by std::ref. This is the line in
                                               // question

    [Conditionally wait for Resource B to be created on thread t]

    [Recreate Resource A now that B has been created]

    [Notify condition on thread t that A has been recreated]

    [Handle A stuff and do stuff with this]
}
0

There are 0 answers