C++并發編程-14. 利用柵欄實現同步

前文我們通過原子操作實戰實現了無鎖隊列,今天完善一下無鎖的原子操作剩余的知識,包括Relaese和Acquire內存序在什么情況下是存在危險的,以及我們可以利用柵欄機制實現同步等等。

線程可見順序

  • 我們提到過除了memory_order_seq_cst順序,其他的順序都不能保證原子變量修改的值在其他多線程中看到的順序是一致的。

但是可以通過同步機制保證一個線程對原子變量的修改對另一個原子變量可見。通過“Syncronizes With” 的方式達到先行的效果。

但是我們說的先行是指 “A Syncronizes With B ”, 如果A 的結果被B讀取,則A 先行于B。

有時候我們線程1對A的store操作采用release內存序,而線程2對B的load采用acquire內存序,并不能保證A 一定比 B先執行。因為兩個線程并行執行無法確定先后順序,我們指的先行不過是說如果B讀取了A操作的結果,則稱A先行于B。

我們看下面的一段案例

#include <iostream>
#include <atomic>
#include <thread>
#include <cassert>
std::atomic<bool> x, y;
std::atomic<int> z;
void write_x()
{x.store(true, std::memory_order_release); //1
}
void write_y()
{y.store(true, std::memory_order_release); //2
}
void read_x_then_y()
{while (!x.load(std::memory_order_acquire));if (y.load(std::memory_order_acquire))   //3++z;
}
void read_y_then_x()
{while (!y.load(std::memory_order_acquire));if (x.load(std::memory_order_acquire))   //4++z;
}
// 我們寫一個函數測試,函數TestAR中初始化x和y為false, 啟動4個線程a,b,c,d,分別執行write_x, write_y, read_x_then_y, read_y_then_x.
void TestAR()
{x = false;y = false;z = 0;std::thread a(write_x);std::thread b(write_y);std::thread c(read_x_then_y);std::thread d(read_y_then_x);a.join();b.join();c.join();d.join();assert(z.load() != 0); //5std::cout << "z value is " << z.load() << std::endl;
}

有的讀者可能會覺5處的斷言不會被觸發,他們認為c和d肯定會有一個線程對z執行++操作。他們的思路是這樣的。
1 如果c線程執行read_x_then_y沒有對z執行加加操作,那么說明c線程讀取的x值為true, y值為false。
2 之后d線程讀取時,如果保證執行到4處說明y為true,等d線程執行4處代碼時x必然為true。
3 他們的理解是如果x先被store為true,y后被store為true,c線程看到y為false時x已經為true了,那么d線程y為true時x也早就為true了,所以z一定會執行加加操作。

上述理解是不正確的,我們提到過即便是releas和acquire順序也不能保證多個線程看到的一個變量的值是一致的,更不能保證看到的多個變量的值是一致的。

變量x和y的載入操作3和4有可能都讀取false值(與寬松次序的情況一樣),因此有可能令斷言觸發錯誤。變量x和y分別由不同線程寫出,所以兩個釋放操作都不會影響到對方線程。

看下圖
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

即線程a執行了,但是線程d沒有看見
線程b執行了,但是線程c沒有看見

柵欄

有時候我們可以通過柵欄保證指令編排順序。

看下面一段代碼

#include <atomic>
#include <thread>
#include <assert.h>
std::atomic<bool> x,y;
std::atomic<int> z;
void write_x_then_y()
{x.store(true,std::memory_order_relaxed); // 1y.store(true,std::memory_order_relaxed);   // 2
}
void read_y_then_x()
{while(!y.load(std::memory_order_relaxed));  // 3if(x.load(std::memory_order_relaxed))  // 4++z;
}
int main()
{x=false;y=false;z=0;std::thread a(write_x_then_y);std::thread b(read_y_then_x);a.join();b.join();assert(z.load()!=0);  //5
}

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/915018.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/915018.shtml
英文地址,請注明出處:http://en.pswp.cn/news/915018.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何選擇旅游科技行業云ERP?Oracle NetSuite助力匯智國際數智化升級

2025年4月21日&#xff0c;匯智國際旅游發展有限公司&#xff08;以下簡稱匯智國際&#xff09;攜手 Oracle NetSuite與Hitpoint Cloud &#xff0c;共同參與了匯智國際 Oracle NetSuite 云ERP 項目啟動會。 本次會議標志著匯智國際在數字化轉型道路上邁出了堅實而關鍵的一步&…

深度學習零基礎入門(3)-圖像與神經網絡

好久不見~我又回來了 這一節我們來講一講圖像在計算機中的本質&#xff0c;以及全連接神經網絡的缺陷&#xff0c;進而引出卷積神經網絡一、圖像在計算機中的本質 不知道你有沒有學過數據結構&#xff0c;在講這一部分的時候對數組進行了擴展&#xff0c;講到了廣義表和壓縮矩陣…

http性能測試命令ab

在 Linux系統中&#xff0c; ab&#xff08; ApacheBench&#xff09;是一個用于 測試HTTP服務器性能的 工具。它是 Apache HTTP服務器項目的 一部分&#xff0c;專門設計用來模擬 多個用戶對 服務器發起 并發請求&#xff0c;從而 評估服務器的 負載能力和 響應時間其中&#…

從0開始學習R語言--Day50--ROC曲線

對于已經擬合好的生存模型&#xff0c;我們一般會直接用ROC去評判一下整體的水平&#xff0c;因為很多時候閾值都是我們人為根據實際情況去設定的&#xff0c;這種微調的細節都是在整體模型的擬合程度確定下來后再做的工作。ROC曲線可以提供給我們模型對于二分類變量的區分能力…

從Hyperliquid到AILiquid:一場從極致性能到策略智能的迭代

在Hyperliquid以極致性能引爆鏈上衍生品交易熱潮之后&#xff0c;DeFi市場正迎來新一輪的范式轉變。作為AI原生的下一代交易平臺&#xff0c;AILiquid正式上線并引發市場廣泛關注。該平臺不僅保留了高頻低延遲的交易體驗&#xff0c;更通過AI撮合引擎與鏈上風險控制系統&#x…

磁懸浮軸承轉子不平衡質量控制:陷波濾波器深度解析

在磁懸浮軸承高速旋轉的世界里&#xff0c;不平衡質量如同一個無形的幽靈&#xff0c;引發危險的同步振動&#xff0c;而陷波濾波器&#xff0c;正是精準捕獲并消除這個幽靈的“電磁獵手”。本文將深入剖析其核心原理與實戰設計。引言&#xff1a;同步振動的致命誘惑磁懸浮軸承…

Oracle 數據庫常見等待事件參數詳解

在 Oracle 數據庫的性能診斷與優化中&#xff0c;等待事件是重要的分析依據&#xff0c;而理解等待事件的參數則是深入排查問題的基礎。本文將結合 Oracle 官方文檔&#xff0c;對數據庫中常見的等待事件參數進行詳細解析&#xff0c;幫助數據庫管理員和開發人員更好地解讀等待…

STM32中的CAN總線詳解:從原理到實戰

前言&#xff1a;為什么CAN總線是嵌入式通信的"硬通貨"&#xff1f; 在嵌入式通信領域&#xff0c;CAN&#xff08;Controller Area Network&#xff09;總線憑借其高可靠性、實時性和多節點通信能力&#xff0c;成為汽車電子、工業控制、智能設備等領域的"標配…

【鴻蒙HarmonyOS】鴻蒙app開發入門到實戰教程(二):封裝自定義可復用組件

組件的可復用性&#xff0c;對我們開發的app質量影響很大&#xff0c;看看鴻蒙中如何封裝這種組件 實現效果代碼實現 局部封裝 Builder titleBuilder(title:string 默認標題) {// Builder裝飾此函數&#xff0c;使其能以鏈式調用的方式配置并構建Text組件Row(){Text(title).fo…

Volo-HTTP 0.4.0發布:正式支持 HTTP/2,客戶端易用性大幅提升!

&#x1f916; VOLO簡介 Volo 是由字節跳動服務框架團隊開源的一款高性能、易用的 Rust RPC 框架。 Volo 框架自身開銷極低&#xff0c;并提供了命令行工具與靈活的中間件設計&#xff0c;讓開發者可以輕松上手&#xff0c;享受 Rust 帶來的開發樂趣。 本文介紹自 Volo-HTTP 0…

HTTP相關知識

文章目錄一、基礎特性與規范二、頁面元素與布局三、交互與表單四、網絡通信基礎流程&#xff08;以瀏覽器訪問網頁為例&#xff09;五、配套技術與工具六、知識關聯圖&#xff08;簡化版&#xff09;一、基礎特性與規范 技術定位&#xff1a;HTML 是前端技術棧的核心標記語言&…

機器人-組成結構

目錄 一、發展歷程 二、軟件硬件算法深讀耦合 感知 - 決策 - 執行 1.機械系統&#xff1a; 2.驅動系統&#xff1a; 3.感知系統&#xff1a; 4.控制系統&#xff1a; 5.決策/智能系統&#xff1a; 6.電源系統&#xff1a; 7.總結 一、發展歷程 國際標準化組織(ISO)對…

pycharm結構查看器

v表示整個文件中定義的變量&#xff0c;c是類灰色部分是繼承的父類的&#xff0c;明亮的是定義的&#xff0c;其中m表示定義的函數&#xff0c;f表示

AdsPower 功能詳解 | 應用中心使用指南:插件統一管理更高效、更安全!

當你使用 AdsPower 管理多個瀏覽器環境時&#xff0c;插件的統一配置就變得尤為重要。而「應用中心」正是幫助你集中管理瀏覽器插件的功能入口&#xff0c;搭配瀏覽器環境使用&#xff0c;可以讓賬號操作更便捷、團隊協作更高效。這篇教程將帶你快速上手 AdsPower 應用中心的核…

回歸預測 | MATLAB實現DBO-BP蜣螂算法優化BP神經網絡多輸入單輸出回歸預測

回歸預測 | MATLAB實現DBO-BP蜣螂算法優化BP神經網絡多輸入單輸出回歸預測 目錄 回歸預測 | MATLAB實現DBO-BP蜣螂算法優化BP神經網絡多輸入單輸出回歸預測 預測效果 基本介紹 主要功能 邏輯關聯與算法流程 1. 數據準備 2. DBO優化BP參數 3. BP神經網絡構建 4. 預測與評估 運行…

Lsposed/Xposed

1.環境 1.1 xposed: 安卓8以下使用 下載并安裝xposed installer&#xff0c;模擬器需勾選設置-共享磁盤。 若提示未激活&#xff0c;需要下載sdk sdk下載地址 放置目錄 /sdcard/Android/data/de.robv.android.xposed.installer/cache/downloads/framework/文件權限設置 777 …

3D工業相機是什么?如何選擇和使用它?

工業自動化越來越深入&#xff0c;3D成像技術&#xff08;3D工業相機&#xff09;在工業生產中越來越重要。這篇文章就來說說3D工業相機的技術原理、具體能應用在哪以及怎么選3D相機&#xff0c;給大家做個參考。一、 技術定義與核心特點3D工業相機&#xff0c;簡單說就是一種特…

有哪些好用的原型設計軟件?墨刀、Axure等測評對比

下面是幾款常用原型設計軟件的簡介和對比&#xff0c;重點對墨刀和Axure進行了測評分析&#xff0c;幫助你根據需求做出選擇。&#x1f4a1;常見原型設計軟件一覽工具名稱適合人群平臺支持是否協作是否支持交互墨刀&#xff08;MockingBot&#xff09;產品經理/團隊協作Web、Wi…

二叉樹思想草稿

二叉樹解體兩種思路 是否可以通過遍歷一遍二叉樹得到答案&#xff1f; 用一個traverse函數配合外部變量實現遍歷的思維模式 是否可以定義一個遞歸函數&#xff0c;通過子樹的答案推導出原問題的答案&#xff1f; 遞歸三部曲&#xff1a; 函數定義&#xff0c;參數&#xff0c;返…

如何區分Bug是前端問題還是后端問題?

在軟件測試中,精準定位Bug的歸屬(前端 or 后端)是高效協作的關鍵。以下是系統化的排查方法,結合技術細節和實戰技巧: 1. 核心判斷邏輯 「數據 vs 展示」二分法: 后端問題:數據本身錯誤(API返回錯誤數據/邏輯錯誤/數據庫問題) 前端問題:數據正確但展示異常(UI渲染錯…