C++原子操作
阿新 • • 發佈:2018-12-28
為什麼要使用原子操作
- 讀和寫不是atomic
- 編譯器生成的程式碼有可能改變操作次序
使用mutex
兩個問題都可以解決,但代價比較昂貴,所以用atomic
取代。
用例
#include <atomic> // for atomics
#include <future> // for async() and futures
#include <thread> // for this_thread
#include <chrono> // for durations
#include <iostream>
long data;
std::atomic<bool> readyFlag(false);
void provider ()
{
// after reading a character
std::cout << "<return>" << std::endl;
std::cin.get();
// provide some data
data = 42;
// and signal readiness
readyFlag.store(true);
}
void consumer ()
{
// wait for readiness and do something else
while (!readyFlag.load()) {
std::cout.put('.').flush();
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
// and process provided data
std::cout << "\nvalue : " << data << std::endl;
}
int main ()
{
// start provider and consumer
auto p = std::async(std::launch::async,provider);
auto c = std::async(std::launch::async,consumer);
std::atomic<int> x{0};
int x0 = x;
std::cout << "x = " << x << std::endl;
while ( !x.compare_exchange_strong(x0, x0+1) ) {}
std::cout << "x = " << x << std::endl;
}
編譯後執行:
$ ./atomics
<return>
x = 0
x = 1
....
value : 42
常用介面
假設有一個原子變數a
a.store(val)
:賦值val返回voida.load()
:返回a的拷貝a.exchange(val)
:賦值val並返回舊值a的拷貝a.compare_exchange_strong(exp, des)
a.compare_exchange_weak(exp, des)
上面兩個操作是CAS(compare-and-swap)
操作,比較“某記憶體區內容“和”某給定值“,並且唯有在它們相同時才將記憶體區內容更新為另一個給定的新值。
例如:
bool success = x.compare_exchange_strong(y, z);
// If x==y, make x=z and return true
// Otherwise, set y=x and return false
這兩個操作常用做無鎖演算法