[英]Question about the thread-safety of using shared_ptr
As it's well known that shared_ptr
only guarantees access to underlying control block is thread safe and no guarantee made for accesses to owned object.众所周知, shared_ptr
只保证对底层控制块的访问是线程安全的,不保证对拥有对象的访问。
Then why there is a race condition in the code snippet below :那么为什么下面的代码片段中存在竞争条件:
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
}
In the code snippet above, the owned object of the shared pointer named g_s
are not accessed indeed.在上面的代码片段中,名为g_s
的共享指针的拥有对象确实未被访问。
I am really confused now.我现在真的很困惑。 Could somebody shed some light on this matter?有人可以对此事有所了解吗?
std::shared_ptr<T>
guarantees that access to its control block is thread-safe, but not access to the std::shared_ptr<T>
instance itself, which is generally an object with two data members: the raw pointer (the one returned by get()
) and the pointer to the control block. std::shared_ptr<T>
保证对其控制块的访问是线程安全的,但不能访问std::shared_ptr<T>
实例本身,它通常是一个具有两个数据成员的对象:原始指针(一个get()
返回)和指向控制块的指针。
In your code, the same std::shared_ptr<int>
instance may be concurrently accessed by the two threads;在您的代码中,两个线程可以同时访问同一个std::shared_ptr<int>
实例; f1
reads, and f2
writes. f1
读取, f2
写入。
If the two threads were accessing two different shared_ptr
instances that shared ownership of the same object, there would be no data race.如果两个线程正在访问共享同一对象所有权的两个不同shared_ptr
实例,则不会发生数据竞争。 The two instances would have the same control block, but accesses to the control block would be appropriately synchronized by the library implementation.这两个实例将具有相同的控制块,但对控制块的访问将由库实现适当地同步。
If you need concurrent, race-free access to a single std::shared_ptr<T>
instance from multiple threads, you can use std::atomic<std::shared_ptr<T>>
.如果您需要从多个线程对单个std::shared_ptr<T>
实例进行并发、无竞争的访问,则可以使用std::atomic<std::shared_ptr<T>>
。 (There is also an older interface that can be used prior to C++20, which is deprecated in C++20.) (还有一个在 C++20 之前可以使用的旧接口,在 C++20 中已弃用。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.