The naive boolean negation
std::atomic_bool b;
b = !b;
does not seem to be atomic. I suspect this is because operator!
triggers a cast to plain bool
. How would one atomically perform the equivalent negation? The following code illustrates that the naive negation isn't atomic:
#include <thread>
#include <vector>
#include <atomic>
#include <iostream>
typedef std::atomic_bool Bool;
void flipAHundredThousandTimes(Bool& foo) {
for (size_t i = 0; i < 100000; ++i) {
foo = !foo;
}
}
// Launch nThreads std::threads. Each thread calls flipAHundredThousandTimes
// on the same boolean
void launchThreads(Bool& foo, size_t nThreads) {
std::vector<std::thread> threads;
for (size_t i = 0; i < nThreads; ++i) {
threads.emplace_back(flipAHundredThousandTimes, std::ref(foo));
}
for (auto& thread : threads) thread.join();
}
int main() {
std::cout << std::boolalpha;
Bool foo{true};
// launch and join 10 threads, 20 times.
for (int i = 0; i < 20; ++i) {
launchThreads(foo, 10);
std::cout << "Result (should be true): " << foo << "
";
}
}
The code launches 10 threads, each of which flips the atomic_bool a larrge, even, number of times (100000), and prints out the boolean. This is repeated 20 times.
EDIT: For those who want to run this code, I am using a GCC 4.7 snapshot on ubuntu 11.10 with two cores. The compilation options are:
-std=c++0x -Wall -pedantic-errors -pthread
question from:
https://stackoverflow.com/questions/9806200/how-to-atomically-negate-an-stdatomic-bool 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…