jua*_*nza 40 c++ multithreading atomic c++11
天真的布尔否定
std::atomic_bool b;
b = !b;
Run Code Online (Sandbox Code Playgroud)
似乎不是原子的.我怀疑这是因为operator!触发了一个简单的演员bool.如何以原子方式执行等效否定?以下代码说明了天真的否定不是原子的:
#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 << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
代码启动了10个线程,每个线程都会将atomic_bool翻转为多次,甚至是次数(100000),并打印出布尔值.这重复20次.
编辑:对于那些想要运行此代码的人,我在ubuntu 11.10上使用带有两个内核的GCC 4.7快照.编译选项包括:
-std=c++0x -Wall -pedantic-errors -pthread
Run Code Online (Sandbox Code Playgroud)
int*_*jay 29
b = !b 不是原子的,因为它由read和write组成,每个都是原子操作.
有两种选择:
而不是b使用整数类型(例如b.load()),它可以是0或1,而xor与1:
std::atomic<int> flag(0);
flag ^= 1; //equivalent to flag.fetch_xor(1);
Run Code Online (Sandbox Code Playgroud)
不幸的是,b没有提供b.store(),只提供整体类型.
在循环中执行比较/交换操作,直到成功为止:
std::atomic<bool> flag(false);
bool oldValue = flag.load();
while (!flag.compare_exchange_weak(oldValue, !oldValue)) {}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
8366 次 |
| 最近记录: |