Yurii Komarnytskyi Yurii Komarnytskyi -4 years ago 69
C++ Question

unique_ptr with multithreading

I have some fear about using

unique_ptr
with multithreading without
mutex
. I wrote simplified code below, please take a look. If I check
unique_ptr != nullptr
, is it thread safe?

class BigClassCreatedOnce
{
public:
std::atomic<bool> var;

// A lot of other stuff
};


BigClassCreatedOnce
class instance will be created only once but I'm not sure is it safe to use it between threads.

class MainClass
{
public:
// m_bigClass used all around the class from the Main Thread

MainClass()
: m_bigClass()
, m_thread()
{
m_thread = std::thread([this]() {
while (1)
{
methodToBeCalledFromThread();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
});

// other stuff here

m_bigClass.reset(new BigClassCreatedOnce()); // created only once
}

void methodToBeCalledFromThread()
{
if (!m_bigClass) // As I understand this is not safe
{
return;
}

if (m_bigClass->var.load()) // As I understand this is safe
{
// does something
}
}

std::unique_ptr<BigClassCreatedOnce> m_bigClass;
std::thread m_thread;
};


I just put it into infinity loop to simplify the sample.

int main()
{
MainClass ms;
while (1)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}

Answer Source

If I check unique_ptr != nullptr, is it thread safe

No, it is not thread safe. If you have more than one thread and at least of one of them writes to the shared data then you need synchronization. If you do not then you have a data race and it is undefined behavior.

m_bigClass.reset(new BigClassCreatedOnce()); // created only once

and

if (!m_bigClass)

Can both happen at the same time, so it is a data race.

I would also like to point out that

if (m_bigClass->var.load())

Is also not thread safe. var.load() is, but the access of m_bigClass is not so you could also have a data race there.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download