多线程 std::shared_ptr 读/写
multithread std::shared_ptr read / write
我在使用 std::shared_ptr 时遇到了一个双重错误,并试图了解原因。我在多线程环境中使用 shared_ptr,一个线程有时会替换全局数组中的某些元素
std::shared_ptr<Bucket> globalTable[100]; // global elements storage
使用:
globalTable[idx].reset(newBucket);
另一个线程有时会使用 :
读取此 table
std::shared_ptr<Bucket> bkt(globalTable[pIdx]);
// do calculations with bkt-> items
此后我收到双重释放错误,AddressSanitizer 说第二个代码试图释放一个被第一个代码销毁的对象。怎么可能?据我所知 shared_ptr 必须是完全线程安全的。
并非 std::shared_ptr
上的所有操作都是 thread-safe。
具体来说,reference-counts 是原子管理的,但你 有责任确保你访问的 std::shared_ptr
实例没有被同时修改。
您未能履行该责任,导致 data-race 和预期的未定义行为,在您的案例中表现为 double-free。
重置并不能保证线程安全。
如此处所述,分配和引用计数是线程安全的
To satisfy thread safety requirements, the reference counters are
typically incremented using an equivalent of std::atomic::fetch_add
with std::memory_order_relaxed (decrementing requires stronger
ordering to safely destroy the control block).
如果多个线程访问同一个 shared_ptr 你可能会出现竞争条件。
If multiple threads of execution access the same shared_ptr without
synchronization and any of those accesses uses a non-const member
function of shared_ptr then a data race will occur; the shared_ptr
overloads of atomic functions can be used to prevent the data race.
您的函数 reset 不是 const,因此属于该类别。您需要使用互斥锁或其他同步机制。
我在使用 std::shared_ptr 时遇到了一个双重错误,并试图了解原因。我在多线程环境中使用 shared_ptr,一个线程有时会替换全局数组中的某些元素
std::shared_ptr<Bucket> globalTable[100]; // global elements storage
使用:
globalTable[idx].reset(newBucket);
另一个线程有时会使用 :
读取此 tablestd::shared_ptr<Bucket> bkt(globalTable[pIdx]);
// do calculations with bkt-> items
此后我收到双重释放错误,AddressSanitizer 说第二个代码试图释放一个被第一个代码销毁的对象。怎么可能?据我所知 shared_ptr 必须是完全线程安全的。
并非 std::shared_ptr
上的所有操作都是 thread-safe。
具体来说,reference-counts 是原子管理的,但你 有责任确保你访问的 std::shared_ptr
实例没有被同时修改。
您未能履行该责任,导致 data-race 和预期的未定义行为,在您的案例中表现为 double-free。
重置并不能保证线程安全。
如此处所述,分配和引用计数是线程安全的
To satisfy thread safety requirements, the reference counters are typically incremented using an equivalent of std::atomic::fetch_add with std::memory_order_relaxed (decrementing requires stronger ordering to safely destroy the control block).
如果多个线程访问同一个 shared_ptr 你可能会出现竞争条件。
If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur; the shared_ptr overloads of atomic functions can be used to prevent the data race.
您的函数 reset 不是 const,因此属于该类别。您需要使用互斥锁或其他同步机制。