In my application, I have an int and a bool variable, which are accessed (multiple write/read) by multiple threads. Currently, I am using two mutexes, one for int and one for bool to protect those variables.
I heard about using atomic variables and operators to write lock-free multi-thread program. My questions are
Are these code thread-safe?
double double_m; // double_m is only accessed by current thread. std::atomic<bool> atomic_bool_x; atomic_bool_x = true && (double_m > 12.5); int int_n; // int_n is only accessed by current thread. std::atomic<int> atomic_int_x; std::atomic<int> atomic_int_y; atomic_int_y = atomic_int_x * int_n;
Atomic is a library that provides atomic data types and operations on these data types, as well as memory ordering constraints required for coordinating multiple threads through atomic variables.
In order to solve this problem, C++ offers atomic variables that are thread-safe. The atomic type is implemented using mutex locks. If one thread acquires the mutex lock, then no other thread can acquire it until it is released by that particular thread.
Each instantiation and full specialization of the std::atomic template defines an atomic type. If one thread writes to an atomic object while another thread reads from it, the behavior is well-defined (see memory model for details on data races).
x++ in C and C++ doesn't have atomic behavior.
I'm not an expert or anything, but here's what I know:
std::atomic
simply says that calling load
and store
(and a few other operations) concurrently is well-defined. An atomic operation is indivisible - nothing can happen 'in-between'.std::atomic
is based off of boost::atomic
. If you can, use std
, otherwise use boost
.std
being completely so, however your compiler will need to support C++11std::atomic_bool
. You should not need to use volatile.Also, I believe load
/store
differs from operator=
/operator T
only .load
/store
are atomic
Nevermind. I checked the standard and it appears that the operators are defined in terms of load
/store
/etc, however they may return different things.
Further reading:
Volatile is orthogonal to what you use to implement atomics. In C++ it tells the compiler that certain it is not safe to perform optimizations with that variable. Herb Sutters lays it out:
To safely write lock-free code that communicates between threads without using locks, prefer to use ordered atomic variables: Java/.NET volatile, C++0x atomic, and C-compatible atomic_T.
To safely communicate with special hardware or other memory that has unusual semantics, use unoptimizable variables: ISO C/C++ volatile. Remember that reads and writes of these variables are not necessarily atomic, however.
Finally, to express a variable that both has unusual semantics and has any or all of the atomicity and/or ordering guarantees needed for lock-free coding, only the ISO C++0x draft Standard provides a direct way to spell it: volatile atomic.
(from http://drdobbs.com/article/print?articleId=212701484&siteSectionName=parallel)
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