Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
655 views
in Technique[技术] by (71.8m points)

c++ - About thread-safety of weak_ptr

std::shared_ptr<int> g_s = std::make_shared<int>(1);
void f1()
{
    std::shared_ptr<int>l_s1 = g_s; // read g_s
}

void f2()
{
    std::shared_ptr<int> l_s2 = std::make_shared<int>(3);
    std::thread th(f1);
    th.detach();
    g_s = l_s2; // write g_s
}

Regarding the code above, I know different threads reading and writing the same shared_ptr leads to race conditions. But how about weak_ptr? Is there any race condition in the code below? (My platform is Microsoft VS2013.)

std::weak_ptr<int> g_w;

void f3()
{
    std::shared_ptr<int>l_s3 = g_w.lock(); //2. here will read g_w
    if (l_s3)
    {
        ;/.....
    }
}

void f4()
{
    std::shared_ptr<int> p_s = std::make_shared<int>(1);
    g_w = p_s;

    std::thread th(f3);
    th.detach();
    // 1. p_s destory will motify g_w (write g_w)
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I know I'm late, but this comes up when searching for "weak_ptr thread", and Casey's answer just isn't the whole truth. Both shared_ptr and weak_ptr can be used from threads without further synchronization.

For shared_ptr, there's a lot of documentation (e.g. on cppreference.com or on stackoverflow). You can safely access shared_ptr's that point to the same object from different threads. You just can't bang on the same pointer from two threads. In other words:

// Using p and p_copy from two threads is fine.
// Using p from two threads or p and p_ref from two threads is illegal.
std::shared_ptr<A> p = std::make_shared<A>();
std::shared_ptr<A> &p_ref = p;
std::shared_ptr<A> p_copy = p;

To solve that problem in your code, pass g_s as parameter (by value)* to f1().

For weak pointers, the safety guarantee is hidden in the documentation for weak_ptr::lock:

Effectively returns expired() ? shared_ptr<T>() : shared_ptr<T>(*this), executed atomically.

You can use weak_ptr::lock() to get a shared_ptr from other threads without further synchronization. This is also confirmed here for Boost and in this SO answer by Chris Jester-Young.

Again, you have to make sure not to modify the same weak_ptr from one thread while accessing it from another, so pass g_w into f3() by value as well.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...