1

The implementation of _Sp_counted_base uses atomic counters:

_Atomic_word  _M_use_count;     // #shared
_Atomic_word  _M_weak_count;    // #weak + (#shared != 0)

Why are the counters atomic but the pointer not? Is atomic-count necessary? Are there any examples of its necessity?

(Because std::shared_ptr is not thread-safe, so I consider atomic-count is not necessary.)

user438383
  • 5,716
  • 8
  • 28
  • 43
BBing
  • 152
  • 5

3 Answers3

7

Because std::shared_ptr is not thread-safe, so I consider atomic-count is not necessary.

Your premise is invalid because std::shared_ptr is thread-safe (to an extent). And that's why the reference counters are atomic. From cppreference:

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).

Further reading: std::shared_ptr thread safety explained

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • Thanks, the comment-"thread-safe(to an extent)" seems explains my confusssion. Atomic counters can protect ptr in some cases but not all cases. – BBing Jul 26 '22 at 09:00
  • 1
    @BBing the *control block* is thread safe. neither the pointers nor the pointed-to object are thread safe – Caleth Jul 26 '22 at 09:11
  • @BBing is is the same exact thread safety guarantee that the entire C++ standard library has; accessing *different objects* of any standard library type are not a data race. – Cubbi Jul 26 '22 at 13:39
  • @Cubbi But, for `shared_ptr`, multiple threads accessing the (same) reference count(s) won't cause (for example) double deletion. That's why those counters *need* to be atomic. – Adrian Mole Jul 26 '22 at 13:48
  • @AdrianMole right, I'm just saying shared_ptr is not special: res.on.data.races applies to all stdlib types (it's just most types don't need to synchronize anything as they don't share state between different objects of the same type) – Cubbi Jul 26 '22 at 15:34
0

Your assumption about thread safety is false. std::shared_ptr supports atomic operations since C++11 (the standard in which it was added). See the documentation.

VLL
  • 9,634
  • 1
  • 29
  • 54
0

The access to the data of the object pointed to by the shared_ptr is not automatically thread safe, although the programmer can make it thread safe by synchronising all access via a mutex.

The reference count of shared_ptrs to the shared object is, however sharable across threads. Without this if on thread releases a reference and another thread makes a reference, there is a risk of accessing a deleted object.

doron
  • 27,972
  • 12
  • 65
  • 103