shared_ptr副本

时间:2013-03-22 13:06:31

标签: c++

如果dest可能被另一个线程更新,这是否有效?为什么呢?

template<typename T>
void copy(std::shared_ptr<T>& dest, const std::shared_ptr<T>& src)
{
    dest = src;
}

2 个答案:

答案 0 :(得分:2)

如果在没有同步的情况下从两个线程修改dest,将会发生数据竞争(导致未定义的beheaviour)。

shared_ptr提供的唯一线程安全性是您可以在不同步的情况下修改多个线程的使用计数;换句话说,两个线程可以创建和销毁src的副本,但不能分配给dest

答案 1 :(得分:0)

是的,可以进入另一个线程并将src重置为null或者在开头括号添加引用之间的新值。 shared_ptr中的引用计数本身是线程安全的,但指针/指针不是,并且需要一个互斥锁来防止问题。

考虑:

// Warning: Don't do this
std::shared_ptr<int> src( new int(42) );
std::shared_ptr<int> dest;

std::thread t1( [&] { src.reset(); } ); // Thread 1
std::thread t2( [&] { *src = 1492; } ); // Thread 2
copy( dest, src );                      // Thread 3
t1.join();
t2.join();

这可能导致未定义的行为,具体取决于线程1和2何时执行。

如果删除线程1,则在这些行的末尾,* src将为1492,* dest可以是1492或42,具体取决于执行顺序。

如果删除线程2,那么在这些行的末尾,src将为null dest可以为null或者值为42,具体取决于执行顺序。

在这种情况下,如果共享数据上有读者和编写者或多个写入者,则需要使用互斥锁,在这种情况下,要么包含指针或指针对象。

比较这个主题:std::shared_ptr thread safety explained