Reputation: 4115
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;
Upvotes: 32
Views: 29408
Reputation: 2344
I believe std::atomic
(C++11) and boost.atomic
are equivalent. If std::atomic
is not supported by your compiler yet, use boost::atomic
.
Upvotes: 1
Reputation: 3510
std::atomic
is standard since C++11, and the Boost stuff is older. But since it is standard now, I would prefer std::atomic
.std::atomic
with each C++11 compiler on each platform you want.Without any further information...
std::atomic;
Upvotes: 2
Reputation: 1099
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)
Upvotes: 7
Reputation: 53047
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:
Upvotes: 19