最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go并發(fā)與鎖的兩種方式該如何提效詳解

 更新時(shí)間:2022年12月27日 08:55:11   作者:機(jī)智的程序員小熊  
如果沒有鎖,在我們的項(xiàng)目中,可能會(huì)存在多個(gè)goroutine同時(shí)操作一個(gè)資源(臨界區(qū)),這種情況會(huì)發(fā)生競態(tài)問題(數(shù)據(jù)競態(tài)),下面這篇文章主要給大家介紹了關(guān)于Go并發(fā)與鎖的兩種方式該如何提效的相關(guān)資料,需要的朋友可以參考下

并發(fā)安全,就是多個(gè)并發(fā)體在同一段時(shí)間內(nèi)訪問同一個(gè)共享數(shù)據(jù),共享數(shù)據(jù)能被正確處理。

很多語言的并發(fā)編程很容易在同時(shí)修改某個(gè)變量的時(shí)候,因?yàn)椴僮鞑皇窃拥?,而出現(xiàn)錯(cuò)誤計(jì)算,比如一個(gè)加法運(yùn)算使用中的變量被修改,而導(dǎo)致計(jì)算結(jié)果出錯(cuò),典型的像統(tǒng)計(jì)商品庫存。

個(gè)人建議只要涉及到共享變量統(tǒng)統(tǒng)使用channel,因?yàn)?code>channel源碼中使用了互斥鎖,它是并發(fā)安全的。

我們可以不用,但不可以不了解,手中有糧心中不慌。

并發(fā)不安全的例子

數(shù)組是并發(fā)不安全的,在例子開始前我們要知道append函數(shù)的行為:長度足夠在原數(shù)組cap內(nèi)追加函數(shù),增加len,長度不夠則觸發(fā)擴(kuò)容,申請(qǐng)新數(shù)組cap增加一倍,賦值遷移。

所以在這個(gè)過程中,僅討論擴(kuò)容操作的話可能存在同時(shí)申請(qǐng)并賦值的情況,導(dǎo)致漏掉某次擴(kuò)容增加的數(shù)據(jù)。

var s []int

func appendValue(i int) {
	s = append(s, i)
}

func main() {
	for i := 0; i < 10000; i++ { //10000個(gè)協(xié)程同時(shí)添加切片
		go appendValue(i)
	}
    time.Sleep(2)
    fmt.Println(len(s))
}

比如上例,10000 個(gè)協(xié)程同時(shí)為切片增加數(shù)據(jù),你可以嘗試運(yùn)行一下,打印出來的一定不是 10000 。

  • 以上并發(fā)操作的同一個(gè)資源,專業(yè)名詞叫做臨界區(qū)。
  • 因?yàn)椴l(fā)操作存在數(shù)據(jù)競爭,導(dǎo)致數(shù)據(jù)值意外改寫,最后的結(jié)果與期待的不符,這種問題統(tǒng)稱為競態(tài)問題。

常見于控制商品減庫存,控制余額增減等情況。 那么有什么辦法解決競態(tài)問題呢?

  • 互斥鎖:讓訪問某個(gè)臨界區(qū)的時(shí)候,只有一個(gè) goroutine 可以訪問。
  • 原子操作:讓某些操作變成原子的,這個(gè)后續(xù)討論。

這兩個(gè)思路貫穿了無數(shù)的高并發(fā)/分布式方案,區(qū)別是在一個(gè)進(jìn)程應(yīng)用中使用,還是借助某些第三方手段來實(shí)現(xiàn),比如中間件。獨(dú)孤九劍森羅萬象一定要牢牢記住。

互斥鎖

Go 語言中互斥鎖的用法如下:

var lock sync.Mutex //互斥鎖
lock.Lock() //加鎖
s = append(s, i)
lock.Unlock() //解鎖

在訪問臨界區(qū)的前后加上互斥鎖,就可以保證不會(huì)出現(xiàn)并發(fā)問題。

我們修改還是上一個(gè)4.7.1的例子,為其增加互斥鎖。

var s []int
var lock sync.Mutex

appendValueSafe := func(i int) {
    lock.Lock()
    s = append(s, i)
    lock.Unlock()
}

for i := 0; i < 10000; i++ { //10000個(gè)協(xié)程同時(shí)添加切片
    go appendValueSafe(i)
}
time.Sleep(2)
fmt.Println(len(s))
  • 對(duì)共享變量s的寫入操作加互斥鎖,保證同一時(shí)刻只有一個(gè)goroutine修改內(nèi)容。
  • 加鎖之后到解鎖之前的內(nèi)容,同一時(shí)刻只有一個(gè)訪問,無論讀寫。
  • 無論多少次都輸出10000,不會(huì)再出現(xiàn)競態(tài)問題。
  • 要注意:如果在寫的同時(shí),有并發(fā)讀操作時(shí),為了防止不要讀取到寫了一半數(shù)據(jù),需要為讀操作也加鎖。

讀寫鎖

互斥鎖是完全互斥的,并發(fā)讀沒有修改的情況下是不會(huì)有問題的,也沒有必要在并發(fā)讀的時(shí)候加鎖不然效率會(huì)變低。

用法:

rwlock sync.RWMutex
//讀鎖
rwlock.RLock()
rwlock.RUnlock()

//寫鎖
rwlock.Lock()
rwlock.Unlock()

并發(fā)讀不互斥可以同時(shí),在一個(gè)寫鎖獲取時(shí),其他所有鎖都等待, 口訣:讀讀不互斥、讀寫互斥、寫寫互斥。具體測算速度的代碼可以見4.7.3的源碼,感興趣的可以改下注釋位置看下效率是有很明顯的提升的。

小結(jié)

  • 學(xué)習(xí)了幾個(gè)名詞:臨界區(qū)、競態(tài)問題、互斥鎖、原子操作、讀寫鎖。
  • 互斥鎖:sync.Mutex, 讀寫鎖:sync.RWMutex 都是 sync 包的。
  • 讀寫鎖比互斥鎖效率高。

問題:只加寫鎖可以嗎?為什么?

總結(jié)

到此這篇關(guān)于Go并發(fā)與鎖的兩種方式該如何提效的文章就介紹到這了,更多相關(guān)Go并發(fā)與鎖提效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談Go1.18中的泛型編程

    淺談Go1.18中的泛型編程

    本文主要介紹了Go1.18中的泛型編程,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Go Slice進(jìn)行參數(shù)傳遞如何實(shí)現(xiàn)詳解

    Go Slice進(jìn)行參數(shù)傳遞如何實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了Go Slice進(jìn)行參數(shù)傳遞如何實(shí)現(xiàn)的過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • go下載指定版本的依賴包圖文詳解

    go下載指定版本的依賴包圖文詳解

    由于依賴包的每個(gè)版本都有一個(gè)唯一的目錄,所以在多項(xiàng)目場景中需要使用同一個(gè)依賴包的多版本時(shí)才不會(huì)產(chǎn)生沖突,下面這篇文章主要給大家介紹了關(guān)于go下載指定版本的依賴包的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • golang批量執(zhí)行任務(wù)的通用模板分享

    golang批量執(zhí)行任務(wù)的通用模板分享

    這篇文章主要為大家詳細(xì)介紹了golang實(shí)現(xiàn)批量執(zhí)行任務(wù)的通用模板,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2023-11-11
  • Go每日一庫之quicktemplate的使用

    Go每日一庫之quicktemplate的使用

    quicktemplate快速、功能強(qiáng)大、易于使用的Go模板引擎。比html/模板快20倍,本文我們就詳細(xì)的介紹一下quicktemplate的具體使用,感興趣的可以了解一下
    2021-07-07
  • Go語言關(guān)于幾種深度拷貝(deepcopy)方法的性能對(duì)比

    Go語言關(guān)于幾種深度拷貝(deepcopy)方法的性能對(duì)比

    這篇文章主要介紹了Go語言關(guān)于幾種深度拷貝(deepcopy)方法的性能對(duì)比,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 深入解析golang?bufio

    深入解析golang?bufio

    這篇文章主要介紹了golang?bufio解析,golang的bufio庫使用緩存來一次性進(jìn)行大塊數(shù)據(jù)的讀寫,以此降低IO系統(tǒng)調(diào)用,提升性能,需要的朋友可以參考下
    2022-04-04
  • Go語言實(shí)現(xiàn)猜謎小游戲

    Go語言實(shí)現(xiàn)猜謎小游戲

    這篇文章主要為大家介紹了Go語言實(shí)現(xiàn)猜謎小游戲示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • go?REST?API設(shè)計(jì)模式和反模式示例解析

    go?REST?API設(shè)計(jì)模式和反模式示例解析

    在這篇文章中,我們將探討一些常見的REST?API設(shè)計(jì)模式和開發(fā)者應(yīng)該注意的反模式,我們還將提供Golang和Open?API?Schema的代碼片段來幫助說明這些概念,有需要的朋友可以借鑒參考下
    2023-09-09
  • 手把手教你如何在Goland中創(chuàng)建和運(yùn)行項(xiàng)目

    手把手教你如何在Goland中創(chuàng)建和運(yùn)行項(xiàng)目

    歡迎來到本指南!我們將手把手地教您在Goland中如何創(chuàng)建、配置并運(yùn)行項(xiàng)目,通過簡單的步驟,您將迅速上手這款強(qiáng)大的集成開發(fā)環(huán)境(IDE),輕松實(shí)現(xiàn)您的編程夢想,讓我們一起開啟這段精彩的旅程吧!
    2024-02-02

最新評(píng)論

安吉县| 兰考县| 全州县| 沾益县| 河北区| 紫金县| 东台市| 彩票| 齐齐哈尔市| 泗水县| 邹平县| 印江| 兴山县| 察哈| 安仁县| 都安| 漳州市| 青阳县| 桐梓县| 临猗县| 汉川市| 云浮市| 牟定县| 托克托县| 吉隆县| 芜湖县| 淮滨县| 和平县| 色达县| 大新县| 聊城市| 邢台市| 体育| 兴和县| 晋江市| 北川| 高台县| 鹤峰县| 正定县| 沙洋县| 木里|