亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go語(yǔ)言開(kāi)發(fā)保證并發(fā)安全實(shí)例詳解

 更新時(shí)間:2022年09月02日 09:09:52   作者:Sundar84034  
這篇文章主要為大家介紹了Go語(yǔ)言開(kāi)發(fā)保證并發(fā)安全實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

什么是并發(fā)安全?

高并發(fā)場(chǎng)景下,進(jìn)程、線程(協(xié)程)可能會(huì)發(fā)生資源競(jìng)爭(zhēng),導(dǎo)致數(shù)據(jù)臟讀、臟寫(xiě)、死鎖等問(wèn)題,為了避免此類問(wèn)題的發(fā)生,就有了并發(fā)安全。

這里舉一個(gè)簡(jiǎn)單的例子:

 var data int 
 go func() {
   data++ 
 }() 
 if data == 0 { 
   fmt.Printf("the value is %v.\n", data) 
 }

在這段代碼中

第2行g(shù)o關(guān)鍵字開(kāi)啟了一個(gè)新的協(xié)程,來(lái)執(zhí)行data++操作

第5行,對(duì)data變量進(jìn)行了讀取判斷的操作

以上兩部是由2個(gè)不同線程/協(xié)程運(yùn)行,且沒(méi)有任何措施保證執(zhí)行順序,所以執(zhí)行結(jié)果是不確定的。

  • 沒(méi)有輸出。(第3行是在第5行之前執(zhí)行的)
  • 輸出 the value is 0。(第5行和第6行在第3行之前執(zhí)行)
  • 輸出 the value is 1。(第5行在第3行之前執(zhí)行,但第3行在第6行之前執(zhí)行)

Go如何保證并發(fā)安全

目前了解到的,大概有這3種,Mutex、Channel、Atomic

Mutex

加鎖應(yīng)該是最常見(jiàn)的并發(fā)控制方法,一般分成兩種,樂(lè)觀鎖和悲觀鎖。

鎖是由操作系統(tǒng)的調(diào)度器來(lái)實(shí)現(xiàn)的,鎖通常用來(lái)保護(hù)一段邏輯,

悲觀鎖

悲觀鎖是一種悲觀思想,它總認(rèn)為最壞的情況可能會(huì)出現(xiàn)。不管意料之外的結(jié)果是否會(huì)發(fā)生,只要存在發(fā)生的可能,就在操作這個(gè)資源之前先上鎖。例如互斥鎖、讀寫(xiě)鎖都是悲觀鎖。

在go中,除了automic,其它都是悲觀鎖

悲觀鎖應(yīng)該都是由操作系統(tǒng)的調(diào)度器來(lái)實(shí)現(xiàn)的,通常用來(lái)保護(hù)一段邏輯,主要是通過(guò)阻塞其它線程,保證當(dāng)前時(shí)刻只有一個(gè)線程在對(duì)資源進(jìn)行操作,因此性能相對(duì)較差,浪費(fèi)了計(jì)算機(jī)多核的優(yōu)勢(shì)。

樂(lè)觀鎖

樂(lè)觀鎖的思想與悲觀鎖的思想相反,它總認(rèn)為資源和數(shù)據(jù)不會(huì)被別人所修改,所以讀取不會(huì)上鎖,但是樂(lè)觀鎖在進(jìn)行寫(xiě)入操作的時(shí)候會(huì)判斷當(dāng)前數(shù)據(jù)是否被修改過(guò)。

樂(lè)觀鎖的實(shí)現(xiàn)方案主要包含CAS版本號(hào)機(jī)制

樂(lè)觀鎖適用于多讀的場(chǎng)景,可以提高吞吐量。

版本號(hào)機(jī)制

通過(guò)在數(shù)據(jù)表中,增加一個(gè)版本號(hào)字段,當(dāng)數(shù)據(jù)發(fā)生更新時(shí),版本號(hào)值發(fā)生改變。 例如一個(gè)線程A想要更新變量s的值,在讀取s的值的同時(shí)讀取版本號(hào),在提交更新時(shí),用之前讀到的版本號(hào)值與當(dāng)前的版本號(hào)值進(jìn)行比對(duì),當(dāng)且僅當(dāng)版本號(hào)值一致時(shí),才會(huì)觸發(fā)更新,否則不斷進(jìn)行重試,直到更新成功。

CAS

CAS全名為Compare And Swap,即比較與轉(zhuǎn)換,是一種有名的無(wú)鎖算法。在不使用鎖的情況下,實(shí)現(xiàn)多線程之間的變量同步,也就是在沒(méi)有線程被阻塞的情況下實(shí)現(xiàn)變量的同步,所以也叫非阻塞同步,

互斥鎖

GO使用Sync包的Mutex類型來(lái)實(shí)現(xiàn)互斥鎖,它能保證同時(shí)只有一個(gè)goroutine可以訪問(wèn)資源。

func sample() {
	var l sync.Mutex
	l.Lock()
        defer l.Unlock()
	// so something
}

讀寫(xiě)互斥鎖

GO使用Sync包的RWMutex類型來(lái)實(shí)現(xiàn)互斥鎖。當(dāng)我們?nèi)ゲl(fā)的讀取一個(gè)資源,只要數(shù)據(jù)沒(méi)有發(fā)生寫(xiě)入,是沒(méi)必要加鎖的。因此讀多寫(xiě)少的情況下,使用讀寫(xiě)互斥鎖是更好的選擇,性能更好。

讀寫(xiě)鎖分為兩種:讀鎖和寫(xiě)鎖。

當(dāng)一個(gè)goroutine獲取讀鎖之后,其他的goroutine如果是獲取讀鎖可以順利獲得,如果是獲取寫(xiě)鎖就會(huì)等待;

當(dāng)一個(gè)goroutine獲取寫(xiě)鎖之后,其他的goroutine無(wú)論是獲取讀鎖還是寫(xiě)鎖都會(huì)等待。

package main
import (
	"fmt"
	"sync"
	"time"
)
var (
	wg     sync.WaitGroup
	rwlock sync.RWMutex
)
func write() {
	rwlock.Lock() // 加寫(xiě)鎖
	time.Sleep(10 * time.Millisecond)
	rwlock.Unlock() // 解寫(xiě)鎖
	wg.Done()
}
func read() {
	rwlock.RLock() // 加讀鎖
	time.Sleep(time.Millisecond)
	rwlock.RUnlock() // 解讀鎖
	wg.Done()
}
func main() {
	start := time.Now()
	//讀多
	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go read()
	}
	//寫(xiě)少
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go write()
	}
	wg.Wait()
	end := time.Now()
	fmt.Println(end.Sub(start))
}

以上就是Go語(yǔ)言開(kāi)發(fā)保證并發(fā)安全實(shí)例詳解的詳細(xì)內(nèi)容,更多關(guān)于Go保證并發(fā)安全的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • golang的httpserver優(yōu)雅重啟方法詳解

    golang的httpserver優(yōu)雅重啟方法詳解

    這篇文章主要給大家介紹了關(guān)于golang的httpserver優(yōu)雅重啟的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • Go語(yǔ)言的GOPATH與工作目錄詳解

    Go語(yǔ)言的GOPATH與工作目錄詳解

    這篇文章主要介紹了Go語(yǔ)言的GOPATH與工作目錄詳解,本文詳細(xì)講解了GOPATH設(shè)置、應(yīng)用目錄結(jié)構(gòu)、編譯應(yīng)用等內(nèi)容,需要的朋友可以參考下
    2014-10-10
  • 使用go語(yǔ)言解析xml的實(shí)現(xiàn)方法(必看篇)

    使用go語(yǔ)言解析xml的實(shí)現(xiàn)方法(必看篇)

    下面小編就為大家?guī)?lái)一篇使用go語(yǔ)言解析xml的實(shí)現(xiàn)方法(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Go結(jié)合JavaScript實(shí)現(xiàn)抓取網(wǎng)頁(yè)中的圖像鏈接

    Go結(jié)合JavaScript實(shí)現(xiàn)抓取網(wǎng)頁(yè)中的圖像鏈接

    這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言如何結(jié)合JavaScript實(shí)現(xiàn)抓取網(wǎng)頁(yè)中的圖像鏈接,文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • golang?struct?json?tag的使用以及深入講解

    golang?struct?json?tag的使用以及深入講解

    這篇文章主要給大家介紹了關(guān)于golang?struct?json?tag的使用以及深入講解,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-02-02
  • Go語(yǔ)言中實(shí)現(xiàn)enum枚舉的方法詳解

    Go語(yǔ)言中實(shí)現(xiàn)enum枚舉的方法詳解

    枚舉,即?enum,可用于表示一組范圍固定的值,它能助我們寫(xiě)出清晰、安全的代碼,那么你是否了解過(guò)?Go?中的枚舉呢?下面就跟隨小編一起來(lái)學(xué)習(xí)一下Go語(yǔ)言中實(shí)現(xiàn)enum枚舉的常用方法吧
    2024-02-02
  • Go語(yǔ)言針對(duì)Map的11問(wèn)你知道幾個(gè)?

    Go語(yǔ)言針對(duì)Map的11問(wèn)你知道幾個(gè)?

    Go?Map?的?11?連問(wèn),你頂?shù)昧寺?這篇文章小編為大家準(zhǔn)備了?Go?語(yǔ)言?Map?的?11?連問(wèn),相信大家看完肯定會(huì)有幫助的,感興趣的小伙伴可以收藏一波
    2023-05-05
  • Go語(yǔ)言編程通過(guò)dwarf獲取內(nèi)聯(lián)函數(shù)

    Go語(yǔ)言編程通過(guò)dwarf獲取內(nèi)聯(lián)函數(shù)

    這篇文章主要為大家介紹了Go語(yǔ)言編程通過(guò)dwarf獲取內(nèi)聯(lián)函數(shù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Golang字符串拼接的性能以及原理詳解

    Golang字符串拼接的性能以及原理詳解

    最近在做性能優(yōu)化,有個(gè)函數(shù)里面的耗時(shí)特別長(zhǎng),看里面的操作大多是一些字符串拼接的操作,而字符串拼接在golang里面其實(shí)有很多種實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Golang字符串拼接的性能以及原理的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • Go語(yǔ)言實(shí)現(xiàn)定時(shí)器的原理及使用詳解

    Go語(yǔ)言實(shí)現(xiàn)定時(shí)器的原理及使用詳解

    這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言實(shí)現(xiàn)定時(shí)器的兩種方法:一次性定時(shí)器(Timer)和周期性定時(shí)器(Ticker),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-12-12

最新評(píng)論