Go 原子操作有哪些?

Go atomic包是最輕量級的鎖(也稱無鎖結構),可以在不形成臨界區和創建互斥量的情況下完成并發安全的值替換操作,不過這個包只支持int32/int64/uint32/uint64/uintptr這幾種數據類型的一些基礎操作(增減、交換、載入、存儲等)

概念

原子操作僅會由一個獨立的CPU指令代表和完成。原子操作是無鎖的,常常直接通過CPU指令直接實現。 事實上,其它同步技術的實現常常依賴于原子操作。

使用場景

當我們想要對某個變量并發安全的修改,除了使用官方提供的 mutex,還可以使用 sync/atomic 包的原子操作,它能夠保證對變量的讀取或修改期間不被其他的協程所影響。

atomic 包提供的原子操作能夠確保任一時刻只有一個goroutine對變量進行操作,善用 atomic 能夠避免程序中出現大量的鎖操作。

常見操作

  • 增減Add
  • 載入Load
  • 比較并交換CompareAndSwap
  • 交換Swap
  • 存儲Store

atomic 操作的對象是一個地址,你需要把可尋址的變量的地址作為參數傳遞給方法,而不是把變量的值傳遞給方法

下面將分別介紹這些操作:

增減操作

此類操作的前綴為 Add

func AddInt32(addr *int32, delta int32) (new int32)func AddInt64(addr *int64, delta int64) (new int64)func AddUint32(addr *uint32, delta uint32) (new uint32)func AddUint64(addr *uint64, delta uint64) (new uint64)func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)

需要注意的是,第一個參數必須是指針類型的值,通過指針變量可以獲取被操作數在內存中的地址,從而施加特殊的CPU指令,確保同一時間只有一個goroutine能夠進行操作。

使用舉例:

func add(addr *int64, delta int64) {atomic.AddInt64(addr, delta) //加操作fmt.Println("add opts: ", *addr)
}

載入操作

此類操作的前綴為 Load

func LoadInt32(addr *int32) (val int32)func LoadInt64(addr *int64) (val int64)func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)func LoadUint32(addr *uint32) (val uint32)func LoadUint64(addr *uint64) (val uint64)func LoadUintptr(addr *uintptr) (val uintptr)// 特殊類型: Value類型,常用于配置變更
func (v *Value) Load() (x interface{}) {}

載入操作能夠保證原子的讀變量的值,當讀取的時候,任何其他CPU操作都無法對該變量進行讀寫,其實現機制受到底層硬件的支持。

使用示例:

func load(addr *int64) {fmt.Println("load opts: ", atomic.LoadInt64(&opts))
}

比較并交換

此類操作的前綴為 CompareAndSwap, 該操作簡稱 CAS,可以用來實現樂觀鎖

func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)

該操作在進行交換前首先確保變量的值未被更改,即仍然保持參數 old 所記錄的值,滿足此前提下才進行交換操作。CAS的做法類似操作數據庫時常見的樂觀鎖機制。

需要注意的是,當有大量的goroutine 對變量進行讀寫操作時,可能導致CAS操作無法成功,這時可以利用for循環多次嘗試。

使用示例:

func compareAndSwap(addr *int64, oldValue int64, newValue int64) {if atomic.CompareAndSwapInt64(addr, oldValue, newValue) {fmt.Println("cas opts: ", *addr)return}
}

交換

此類操作的前綴為 Swap

func SwapInt32(addr *int32, new int32) (old int32)func SwapInt64(addr *int64, new int64) (old int64)func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)func SwapUint32(addr *uint32, new uint32) (old uint32)func SwapUint64(addr *uint64, new uint64) (old uint64)func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)

相對于CAS,明顯此類操作更為暴力直接,并不管變量的舊值是否被改變,直接賦予新值然后返回背替換的值。

func swap(addr *int64, newValue int64) {atomic.SwapInt64(addr, newValue)fmt.Println("swap opts: ", *addr)
}

存儲

此類操作的前綴為 Store

func StoreInt32(addr *int32, val int32)func StoreInt64(addr *int64, val int64)func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)func StoreUint32(addr *uint32, val uint32)func StoreUint64(addr *uint64, val uint64)func StoreUintptr(addr *uintptr, val uintptr)// 特殊類型: Value類型,常用于配置變更
func (v *Value) Store(x interface{})

此類操作確保了寫變量的原子性,避免其他操作讀到了修改變量過程中的臟數據。

func store(addr *int64, newValue int64) {atomic.StoreInt64(addr, newValue)fmt.Println("store opts: ", *addr)
}

本文節選于Go合集《常見面試題匯總》
GOLANG ROADMAP一個專注Go語言學習、求職的社區。

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

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

相關文章

Excel之index、MATCH面試題、VLOOKUP函數,

VLOOKUP() 在表格的首列查找指定的數值,并返回表格當前行中指定列處的數值。 結構:VLOOKUP(查找值,查找區域,列序數,匹配條件) 解釋:VLOOKUP(找誰,在哪里找,第幾列,0或1) 1.目的:根據【產品】查找【銷量】 公式:V…

pikachu靶場-XSS

XSS: XSS(跨站腳本)概述 Cross-Site Scripting 簡稱為“CSS”,為避免與前端疊成樣式表的縮寫"CSS"沖突,故又稱XSS。一般XSS可以分為如下幾種常見類型: 1.反射性XSS; 2.存儲型XSS; 3.DOM型XSS; …

QT的UI入門

二、UI入門 QWidget類(熟悉) QWidget類是所有組件和窗口的基類,內部包含了一些基礎的界面特性。 常用屬性: 修改坐標 x : const int 橫坐標,每個圖形的左上角為定位點,橫軸的零點在屏幕的最左邊&#xff0c…

js實現復制功能

一、具體場景 前端有時需要實現點擊按鈕復制的功能,這個時候就不能讓用戶去手動選擇內容右鍵復制了。 二、實現方式 1. document.execCommand (1)具體實現 復制時,先選中文本,然后調用document.execCommand(‘copy’)…

171基于matlab的隨機共振微弱信號檢測

基于matlab的隨機共振微弱信號檢測,隨機共振描述了過阻尼布朗粒子受周期性信號和隨機噪聲的共同作用下,在非線性雙穩態系統中所發生的躍遷現象. 隨機共振可用于弱信號的檢測。程序已調通,可直接運行。

共享之力:分布式計算的奇跡

在信息時代的浪潮中,分布式計算作為一種革命性的技術,已經深刻地改變了我們對計算和數據處理的理解方式。其發展歷程既是一段精彩的科技史,也是一段充滿探索與突破的冒險故事,從最初的概念探索到如今的普及應用,分布式…

HashMap 源碼學習-jdk1.8

1、一些常量的定義 這里針對MIN_TREEIFY_CAPACITY 這個值進行解釋一下。 java8里面,HashMap 的數據結構是數組 (鏈表或者紅黑樹),每個數組節點下可能會存在鏈表和紅黑樹之間的轉換,當同一個索引下面的節點超過8個時…

【Webpack】處理字體圖標和音視頻資源

處理字體圖標資源 1. 下載字體圖標文件 打開阿里巴巴矢量圖標庫open in new window選擇想要的圖標添加到購物車,統一下載到本地 2. 添加字體圖標資源 src/fonts/iconfont.ttf src/fonts/iconfont.woff src/fonts/iconfont.woff2 src/css/iconfont.css 注意字體…

[計算機網絡]---TCP協議

前言 作者:小蝸牛向前沖 名言:我可以接受失敗,但我不能接受放棄 如果覺的博主的文章還不錯的話,還請點贊,收藏,關注👀支持博主。如果發現有問題的地方歡迎?大家在評論區指正 目錄 一 、TCP協…

Java并發基礎:原子類之AtomicBoolean全面解析

本文概要 AtomicBoolean類優點在于能夠確保布爾值在多線程環境下的原子性操作,避免了繁瑣的同步措施,它提供了高效的非阻塞算法實現,可以大大提成程序的并發性能,AtomicBoolean的API設計非常簡單易用。 AtomicBoolean核心概念 …

P1024 [NOIP2001 提高組] 一元三次方程求解

P1024 [NOIP2001 提高組] 一元三次方程求解 純代碼記錄 #include <iostream> #include <math.h> using namespace std; double a,b,c,d; double res[3];//用于存放三個解 int resCount;inline double F(double x)//三次函數 {return a*pow(x,3)b*pow(x,2)c*xd; }//…

web前端開發this指向問題

? 函數內部中的 this 指向誰&#xff0c;不是在函數定義時決定的&#xff0c;而是在函數第一次調用并執行的時候決定的 1. call 方法 語法&#xff1a;函數名.call(調用者, 參數1, …) 作用&#xff1a;函數被借用時&#xff0c;會立即執行&#xff0c;并且函數體內的this會…

Facebook Horizon:探索虛擬現實中的社交空間

隨著科技的不斷進步&#xff0c;虛擬現實&#xff08;VR&#xff09;技術正成為社交互動和娛樂體驗的新前沿。在這個數字時代&#xff0c;Facebook作為全球最大的社交媒體平臺之一&#xff0c;正在引領虛擬社交的新時代&#xff0c;其推出的虛擬社交平臺Facebook Horizon成為了…

Tomcat線程池原理(下篇:工作原理)

文章目錄 前言正文一、執行線程的基本流程1.1 JUC中的線程池執行線程1.2 Tomcat 中線程池執行線程 二、被改造的阻塞隊列2.1 TaskQueue的 offer(...)2.2 TaskQueue的 force(...) 三、總結 前言 Tomcat 線程池&#xff0c;是依據 JUC 中的線程池 ThreadPoolExecutor 重新自定義…

深入理解C語言(5):程序環境和預處理詳解

文章主題&#xff1a;程序環境和預處理詳解&#x1f30f;所屬專欄&#xff1a;深入理解C語言&#x1f4d4;作者簡介&#xff1a;更新有關深入理解C語言知識的博主一枚&#xff0c;記錄分享自己對C語言的深入解讀。&#x1f606;個人主頁&#xff1a;[?]的個人主頁&#x1f3c4…

Imagewheel私人圖床搭建結合內網穿透實現無公網IP遠程訪問教程

文章目錄 1.前言2. Imagewheel網站搭建2.1. Imagewheel下載和安裝2.2. Imagewheel網頁測試2.3.cpolar的安裝和注冊 3.本地網頁發布3.1.Cpolar臨時數據隧道3.2.Cpolar穩定隧道&#xff08;云端設置&#xff09;3.3.Cpolar穩定隧道&#xff08;本地設置&#xff09; 4.公網訪問測…

flutter 文件上傳組件和大文件分片上傳

文件分片上傳 資料 https://www.cnblogs.com/caijinglong/p/11558389.html 使用分段上傳來上傳和復制對象 - Amazon Simple Storage Service 因為公司使用的是亞馬遜的s3桶 下面是查閱資料獲得的 亞馬遜s3桶的文件上傳分片 分段上分為三個步驟&#xff1a;開始上傳、上傳對…

CSP-J 2023 T3 一元二次方程

文章目錄 題目題目背景題目描述輸入格式輸出格式樣例 #1樣例輸入 #1樣例輸出 #1 提示 題目傳送門題解思路總代碼 提交結果尾聲 題目 題目背景 眾所周知&#xff0c;對一元二次方程 a x 2 b x c 0 , ( a ≠ 0 ) ax ^ 2 bx c 0, (a \neq 0) ax2bxc0,(a0)&#xff0c;可…

STM32G030C8T6:定時器1ms中斷(以64MHz外部晶振為例)

本專欄記錄STM32開發各個功能的詳細過程&#xff0c;方便自己后續查看&#xff0c;當然也供正在入門STM32單片機的兄弟們參考&#xff1b; 本小節的目標是&#xff0c;系統主頻64 MHZ,采用高速外部晶振&#xff0c;通過定時器3 每秒中斷控制 PB9 引腳輸出高低電平&#xff0c;從…

20240222作業

完善對話框&#xff0c;點擊登錄對話框&#xff0c;如果賬號和密碼匹配&#xff0c;則彈出信息對話框&#xff0c;給出提示“登錄成功"&#xff0c;提供一個Ok按鈕&#xff0c;用戶點擊OK后&#xff0c;關閉登錄界面&#xff0c;跳轉到其他界面 如果賬號和密碼不匹配&…