shared_ptr.get()可以被多个线程调用,而另一个线程锁定并调用shared_ptr.swap()吗?

Can shared_ptr.get() be called by multiple threads while another thread locks and calls shared_ptr.swap()?

本文关键字:调用 线程 shared ptr 另一个 锁定 swap get      更新时间:2023-10-16

我想知道这是否与shared_ptr安全。请原谅我的伪代码:

Thread 1:
do lock
ReadOnlyObj obj = make_shared<ReadOnlyObj>();
some_shared_ptr.swap(obj);
do unlock
Thread 2-N:
//no lock
some_shared_ptr->getterOnObj();

CPP参考说

所有成员函数(包括复制构造函数和拷贝赋值)都可以在shared_ptr的不同实例上由多个线程调用,而无需额外的同步,即使这些实例是相同对象的副本并共享所有权。如果多个执行线程访问同一个shared_ptr而没有同步,并且其中任何一个访问都使用了shared_ptr的非const成员函数,则会发生数据争用,可以使用原子函数的shared_ptr重载来防止数据争用。

但是,根据GNU文档:

Boost shared_ptr(在GCC中使用)具有一个聪明的无锁算法来避免竞争条件,但这依赖于处理器支持原子比较和交换指令。对于其他平台,有使用互斥锁的回退。Boost(从1.35版本开始)包括几种不同的实现,预处理器根据编译器、标准库、平台等选择一种实现。对于libstdc++中的shared_ptr版本,编译器和库是固定的,这使得事情变得简单得多:我们有一个原子CAS,或者没有,详细信息请参见下面的锁策略。

据我所知,intel x86_64支持CAS。

那么,对于我的问题:

shared_ptr::swap是非const。Get和->()是const。考虑到上面列出的使用场景,我还必须锁定get/->吗?

我想我自己在boost文档中找到了答案。

//--- Example 3 ---
// thread A
p = p3; // reads p3, writes p
// thread B
p3.reset(); // writes p3; undefined, simultaneous read/write

我要做的是同时读写,这是未定义的/不安全的