C++內(nèi)存序memory_order的具體操作
C++ 原子操作提供 6種內(nèi)存序(memory_order),分別控制編譯器和 CPU 如何對(duì)內(nèi)存操作進(jìn)行重排序優(yōu)化,確保并發(fā)程序在多線程之間的行為可控、正確。
所有內(nèi)存序(memory_order)
C++ 中 std::memory_order 的 6 種選項(xiàng)如下:
| 枚舉值 | 中文名 | 簡(jiǎn)要說(shuō)明 |
|---|---|---|
| memory_order_relaxed | 放松序 | 不保證任何順序,只保證原子性 |
| memory_order_consume | 消費(fèi)序(已廢棄趨勢(shì)) | 數(shù)據(jù)依賴同步,僅限依賴關(guān)系(不推薦使用) |
| memory_order_acquire | 獲取序 | 保證本線程之后的操作不會(huì)被重排到原子操作前 |
| memory_order_release | 釋放序 | 保證本線程之前的操作不會(huì)被重排到原子操作后 |
| memory_order_acq_rel | 獲取 + 釋放序 | 同時(shí)保證 acquire + release 的效果,適用于 read-modify-write 操作 |
| memory_order_seq_cst | 順序一致性(默認(rèn)) | 最強(qiáng)的保證:所有線程中看起來(lái)像是全局有序執(zhí)行 |
簡(jiǎn)明圖解理解(線程內(nèi)操作順序)
- relaxed: 無(wú)序(性能最好,但易出錯(cuò))
- acquire: 不能把后面的操作移到前面
- release: 不能把前面的操作移到后面
- acq_rel: 二者兼具
- seq_cst: 所有線程觀察到的執(zhí)行順序一致
常見(jiàn)用法示例對(duì)比
默認(rèn)順序一致性memory_order_seq_cst
#include <atomic>
std::atomic<int> x{0}; // 初始化為 0
x.store(10); // store (默認(rèn) seq_cst)
int v = x.load(); // load (默認(rèn) seq_cst)順序一致性:多線程中所有原子操作全局有序,易于理解但開(kāi)銷較大。
放松序 memory_order_relaxed
#include <atomic>
std::atomic<int> x{0}; // 初始化為 0
// 線程 A
x.store(10, std::memory_order_relaxed); // 原子寫(xiě),不保證順序
// 線程 B
int value = x.load(std::memory_order_relaxed); // 原子讀,不保證看到更新
獲取 / 釋放語(yǔ)義:典型鎖實(shí)現(xiàn)方式
#include <atomic>
std::atomic<bool> flag{false}; // 默認(rèn)未設(shè)置
// 線程 A:寫(xiě)線程
data = 123; // 假設(shè) data 是共享變量
flag.store(true, std::memory_order_release); // 發(fā)布 data 已準(zhǔn)備好
// 線程 B:讀線程
if (flag.load(std::memory_order_acquire)) {
// 這里看到 flag == true
// 根據(jù) acquire 語(yǔ)義:保證看到的 data = 123
std::cout << data << std::endl;
}
這就是經(jīng)典的 “寫(xiě)線程 release,讀線程 acquire” 搭配,確保讀線程看到完整寫(xiě)入的數(shù)據(jù)。
atomic_flag使用場(chǎng)景建議的 memory_order
| 操作類型 | 推薦的 memory_order |
|---|---|
| flag.test_and_set | std::memory_order_acquire |
| flag.clear | std::memory_order_release |
小結(jié)
| 序名 | 用途 | 是否有序 | 性能 | 說(shuō)明 |
|---|---|---|---|---|
| relaxed | 最快的,不同步 | ? | ?????? | 僅原子性,無(wú)順序 |
| acquire | 用于加鎖 | ?(后有序) | ???? | 加鎖讀 |
| release | 用于解鎖 | ?(前有序) | ???? | 解鎖寫(xiě) |
| acq_rel | 讀寫(xiě)同時(shí) | ? | ?? | 用于 fetch_add 等 |
| seq_cst | 最強(qiáng)順序保證 | ??? | ?? | 默認(rèn)值,全局有序 |
| consume | 基本棄用 | ? | ? | 不推薦 |
到此這篇關(guān)于C++內(nèi)存序memory_order的具體操作的文章就介紹到這了,更多相關(guān)C++ memory_order內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)鏈表與文件存取的示例代碼
這篇文章主要和大家分享C語(yǔ)言實(shí)現(xiàn)鏈表與文件存取的示例代碼,可以實(shí)現(xiàn)建立鏈表,然后把鏈表數(shù)據(jù)存儲(chǔ)到文件中,然后把文件數(shù)據(jù)存儲(chǔ)到數(shù)組中并輸出,感興趣的可以學(xué)習(xí)一下2022-04-04
C語(yǔ)言示例講解結(jié)構(gòu)體的聲明與初始化方法
結(jié)構(gòu)體是一些值的集合,這些值稱為成員變量,結(jié)構(gòu)體的每個(gè)成員可以是不同類型的變量。本文將通過(guò)示例為大家詳細(xì)講講C語(yǔ)言中結(jié)構(gòu)體的使用,需要的可以參考一下2022-07-07
C++中類的成員函數(shù)及內(nèi)聯(lián)函數(shù)使用及說(shuō)明
這篇文章主要介紹了C++中類的成員函數(shù)及內(nèi)聯(lián)函數(shù)使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
用C實(shí)現(xiàn)PHP擴(kuò)展 Fetch_Url 類數(shù)據(jù)抓取的方法
該擴(kuò)展是基于libcurl基礎(chǔ)實(shí)現(xiàn)的網(wǎng)頁(yè)數(shù)據(jù)抓取2013-04-04
Visual Studio 2019 DLL動(dòng)態(tài)庫(kù)連接實(shí)例(圖文教程)
這篇文章主要介紹了Visual Studio 2019 DLL動(dòng)態(tài)庫(kù)連接實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03

