Go併發程式設計之CAS操作

2022-09-23 18:39:09 字數 1207 閱讀 8811

一、前言 go語言類似j**a juc包也提供了一些列用於多執行緒之間進行同步的措施,比如低階的同步措施有 鎖、cas、原子變數操作類。相比j**a來說go提供了獨特的基於通道的同步措施。我們先來看看go中cas操作 二、cas操作 go中的cas操作與j**a中類似,都是借用了cpu提供的原子性指令來實現。

go語言類似j**a juc包也提供了一些列用於多執行緒之間進行同步的措施,比如低階的同步措施有 鎖、cas、原子變數操作類。相比j**a來說go提供了獨特的基於通道的同步措施。本節我們先來看看go中cas操作

go中的cas操作與j**a中類似,都是借用了cpu提供的原子性指令來實現。cas操作修改共享變數時候不需要對共享變數加鎖,而是通過類似樂觀鎖的方式進行檢查,本質還是不斷的占用cpu 資源換取加鎖帶來的開銷(比如上下文切換開銷)。下面乙個例子使用cas來實現計數器

package main

import (

"fmt"

"sync"

"sync/atomic"

)var (

counter int32 //計數器

wg sync.waitgroup //訊號量

)func main()

//3.等待子執行緒結束

wg.wait()

fmt.println(counter)

}func inccounter(index int) else

}fmt.printf("thread,%d,spinnum,%d\n",index,spinnum)

}如上**main執行緒首先建立了5個訊號量,然後開啟五個執行緒執行inccounter方法

inccounter內部執行**2.1 使用cas操作遞增counter的值, atomic.compareandswapint32具有三個引數,第乙個是變數的位址,第二個是變數當前值,第三個是要修改變數為多少,該函式如果發現傳遞的old值等於當前變數的值,則使用第三個變數替換變數的值並返回true,否則返回false。

這裡之所以使用無限迴圈是因為在高併發下每個執行緒執行cas並不是每次都成功,失敗了的執行緒需要重寫獲取變數當前的值,然後重新執行cas操作。讀者可以把執行緒數改為10000或者更多會發現輸出thread,5329,spinnum,1其中1說明該執行緒嘗試了兩個cas操作,第二次才成功。

go中cas操作具有原子性,在解決多執行緒操作共享變數安全上可以有效的減少使用鎖所帶來的開銷,但是這是使用cpu資源做交換的。

Go併發程式設計之美 Load Store操作

一 前言 go語言類似j a juc包也提供了一些列用於多執行緒之間進行同步的措施,比如低階的同步措施有 鎖 cas 原子變數操作類。相比j a來說go提供了獨特的基於通道的同步措施。本節我們先來看看go中load store操作 二 load store操作 go中的load和store提供了原子...

併發程式設計(五) CAS

在atomic包中,大多數類都是借助unsafe類來實現的,如以下 public static atomicinteger count new atomicinteger 0 private static void add incrementandget 方法的實現如下 public final i...

go併發程式設計之二 原子性

原子性相關的概念 我們知道redis操作是原子性的,究其具體原因是因為,redis服務是單執行緒的,當多個客戶端傳送命令 到服務端執行時,所有的命令會進入佇列,依次執行,如下圖 原子性是指的某種東西不可分割或者不可中斷的一種屬性。在考慮原子性時,經常需要做的第一件事是定義上下文或作用域,這個操作將被...