C++11 introduced the std::atomic<>
template library. The standard specifies the store()
and load()
operations to atomically set / get a variable shared by more than one thread.
My question is are assignment and access operations also atomic?
Namely, is:
std::atomic<bool> stop(false);
...
void thread_1_run_until_stopped()
{
if(!stop.load())
/* do stuff */
}
void thread_2_set_stop()
{
stop.store(true);
}
Equivalent to:
void thread_1_run_until_stopped()
{
if(!stop)
/* do stuff */
}
void thread_2_set_stop()
{
stop = true;
}
Are assignment and access operations for non-reference types also atomic?
Yes, they are. atomic<T>::operator T
and atomic<T>::operator=
are equivalent to atomic<T>::load
and atomic<T>::store
respectively. All the operators are implemented in the atomic class such that they will use atomic operations as you would expect.
I'm not sure what you mean about "non-reference" types? Not sure how reference types are relevant here.
You can do both, but the advantage of load()
/store()
is that they allow to specify memory order. It is important sometimes for performance, where you can specify std::memory_order_relaxed
while atomic<T>::operator T
and atomic<T>::operator=
would use the most safe and slow std::memory_order_seq_cst
. Sometimes it is important for correctness and readability of your code: although the default std::memory_order_seq_cst
is most safe thus most likely to be correct, it is not immediately clear for the reader what kind of operation (acquire/release/consume) you are doing, or whether you are doing such operation at all (to answer: isn't relaxed order sufficient here?).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With