我在堆上分配了一些很少修改但需要快速读取访问的数据结构。一个示例是在堆上分配的结构,许多线程以只读方式非常频繁地访问该结构。auto_ptr
需要定期重写此结构并避免锁定争用,重写它并快速与结构的新auto_ptr
实例交换指针。
我从CopyOnWriteArrayList
Java 中得到了这个想法,并希望在 C++ 中执行类似的性能。
我在堆上分配了一些很少修改但需要快速读取访问的数据结构。一个示例是在堆上分配的结构,许多线程以只读方式非常频繁地访问该结构。auto_ptr
需要定期重写此结构并避免锁定争用,重写它并快速与结构的新auto_ptr
实例交换指针。
我从CopyOnWriteArrayList
Java 中得到了这个想法,并希望在 C++ 中执行类似的性能。
std::auto_ptr
reset()
在调用非常量成员(如您所建议的)时没有任何线程安全保证。此外,std::unique_ptr
您应该考虑作为替代的auto_ptr
as也没有auto_ptr
被有效地弃用。
std::shared_ptr
确实提供了这样的线程安全保证。
您通常可以保证shared_ptr
引用计数是以原子方式操作的,这意味着在创建 a 的副本时您可以安全地避免数据竞争shared_ptr
,前提是此时没有人正在修改shared_ptr
。
考虑以下用于您的shared_ptr
. 您有一个shared_ptr<string> sharedString;
当前指向std::string
. 许多线程调用get()
来检索指向字符串的指针是安全的。他们也可以这样创建自己的共享指针:shared_ptr<string> myString = sharedString;
,前提是没有人更改共享指针指向的内容。
现在,让我们返回并修复示例中存在的竞争条件。当需要更改全局共享指针指向的内容时,线程可能正在制作它的副本——这是一个问题,因为它可能使副本处于不一致的状态。因此,我们必须确保以原子方式更改和复制它。
幸运的是,shared_ptr
它提供了许多 C++11 原子操作的特化:atomic_load
、atomic_store
和atomic_exchange
.
制作 的副本时shared_ptr
,使用atomic_load
,更新 时shared_ptr
,使用atomic_store
。
这样做很重要,原因有两个。
现在,重要的是要注意在 a 上使用线程安全操作shared_ptr
不会为其指向的类型提供任何线程安全性。您始终必须注意以线程安全的方式使用指向的对象。
您可以使用 reset() 即时重新分配 auto_ptr,顺便说一下,它会破坏以前指向的对象实例。
但是,auto_ptr 已被 unique_ptr 弃用,它有一个 swap() 函数,似乎有点坚持你正在寻找的东西。
请记住,这些类不是线程安全的。