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

GO中sync包自由控制并發(fā)示例詳解

 更新時間:2022年08月04日 16:01:45   作者:六號積極分子  
這篇文章主要為大家介紹了GO中sync包自由控制并發(fā)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

資源競爭

channel 常用于并發(fā)通信,要保證并發(fā)安全,主要使用互斥鎖。在并發(fā)的過程中,當一個內(nèi)存被多個 goroutine 同時訪問時,就會產(chǎn)生資源競爭的情況。這塊內(nèi)存也可以稱為共享資源。

并發(fā)時對于共享資源必然會出現(xiàn)搶占資源的情況,如果是對某資源的統(tǒng)計,很可能就會導(dǎo)致結(jié)果錯誤。為保證只有一個協(xié)程拿到資源并操作它,可以引入互斥鎖 sync.Mutex。

sync.Mutex

互斥鎖,指的是并發(fā)時,在同一時刻只有一個協(xié)程執(zhí)行某段代碼,其他協(xié)程只有等待該協(xié)程執(zhí)行完成后才能繼續(xù)執(zhí)行。

var (sum int 
 mutex sync.Mutex)
func add(i int){
    mutex.Lock()
    sum+=i
    mute.Unlock()
}

使用 mutex 加鎖保護 sum+ =i 的代碼片段,這樣這個片段區(qū)就無法同時被多個協(xié)程訪問,當有協(xié)程進入該片段區(qū),那其他的協(xié)程就只有等待,以此保證臨界區(qū)的并發(fā)安全。

sync.Mutex 只有 Lock()和 Unlock() 方法,它們是成對存在的,且Lock后一定要執(zhí)行Unlock進行釋放鎖。所以可以使用 defer 語句釋放鎖,以保證鎖一定會被釋放。

func add(i int){
    mutex.Lock()
    defer mutex.Unlock()
    sum += i
}

sync.RWMutex

上面例子是對 sum 寫操作時使用sync.Mutex 保證并發(fā)安全,當多個協(xié)程進行讀取操作時,避免因并發(fā)產(chǎn)生讀取數(shù)據(jù)不正確,也是可以使用互斥鎖 sync.Mutex。

func getSum(){
    mutex.Lock()
    defer mutex.Unlock()
    b:=sum
    return b
}

多個協(xié)程 goroutine 同時讀寫的資源競爭問題解決,還需要考慮性能問題,每次讀寫共享資源都加鎖,也會導(dǎo)致性能低。

多個協(xié)程并發(fā)進行讀寫時會遇到以下情況:

  • 寫時不能同時讀,易讀到臟數(shù)據(jù)
  • 讀時不能同時寫,因為會導(dǎo)致結(jié)果不一致
  • 讀時同時寫,因數(shù)據(jù)不變,無論多少個 goroutine 讀都是并發(fā)安全

使用讀寫鎖 sync.RWMutex 優(yōu)化代碼:

var mutex sync.RWMutex
func readSum() int {
    mutex.RLock()
    defer mutex.RUnlock()
    b := sum
    return b
}

讀寫鎖的性能比互斥鎖性能好。

sync.WaitGroup

為了能夠監(jiān)聽所有的協(xié)程的執(zhí)行,一旦所有的goroutine 都執(zhí)行完成,程序應(yīng)當及時退出節(jié)省時間提高性能。通過使用 sync.WaitGroup 來解決。使用步驟如下:

  • 聲明一個 sync.WaitGroup ,通過 add 方法增加計數(shù)器值,有幾個協(xié)程就計算幾個
  • 每個協(xié)程結(jié)束后就調(diào)用 Done 方法,主要是讓計數(shù)器減1
  • 最后調(diào)用 Wait 方法一直等待,直到計數(shù)器為 0 時,所有跟蹤的協(xié)程都執(zhí)行完畢
func run() {
    var wg sync.WaitGroup
    wg.Add(100)
    for i := 0; i < 100; i++ {
        go func() {
            defer wg.Done()
            add(10)
        }()
    }
    wg.Wait()
}

通過 sync.WaitGroup 可以很好地跟蹤協(xié)程.

sync.Once

sync.Once 作用是讓代碼只執(zhí)行一次。詳細使用是調(diào)用方法 once.Do 方法,具體實現(xiàn):

func main(){
    var once sync.once
    oneFunc := func(){
        println("once func")
    }
    once.Do(oneFunc)
}

sync.Once 適用于創(chuàng)建某個對象的單例、只加載一次的資源等只執(zhí)行一次的場景。

sync.Cond

使用 sync.WaitGroup 主要是控制等待所有的協(xié)程都執(zhí)行完畢,才最終完成。但是當遇到場景是,只有等待所有條件都準備好才開始。sync.Cond 相當于發(fā)號施令,只有通知執(zhí)行所有的協(xié)程才可以執(zhí)行,重點是所有協(xié)程需等待喚醒才可以開始。

所以 sync.Cond 具有阻塞協(xié)程和喚醒協(xié)程的功能。詳細的用法:

  • 通過 sync.NewCond 函數(shù)生成一個 *sync.Cond,用于阻塞和喚醒協(xié)程
  • 調(diào)用 cond.Wait() 方法阻塞當前協(xié)程等待,需要注意調(diào)用 cond.Wait() 方法要加鎖
  • 調(diào)用 cond.Broadcast() 后所有協(xié)程才開始執(zhí)行
func run() {
    cond := sync.NewCond(&amp;sync.Mutex{})
    var wg sync.WaitGroup
    wg.Add(101)
    for i := 0; i &lt; 100; i++ {
        go func(num int) {
            defer wg.Done()
            fmt.Println(num, "號正在 awaiting......")
            cond.L.Lock()
            cond.Wait() //等待所有協(xié)程準備完成
            fmt.Println(num, "號開始跑……")
            cond.L.Unlock()
        }(i)
    }
    // 等待所有的協(xié)程都進入 wait 狀態(tài)
    time.Sleep(2*time.Second)
    go func() {
        defer wg.Done()
        // 所有都準備完成,開始
        cond.Broadcast()
    }()
    // 防止函數(shù)提前返回退出
    wg.Wait()
}

以上就是GO中sync包自由控制并發(fā)示例詳解的詳細內(nèi)容,更多關(guān)于GO sync包控制并發(fā)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • go code review 代碼調(diào)試

    go code review 代碼調(diào)試

    這篇文章主要為大家介紹了go code review 代碼調(diào)試方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • go語言開發(fā)中如何優(yōu)雅得關(guān)閉協(xié)程方法

    go語言開發(fā)中如何優(yōu)雅得關(guān)閉協(xié)程方法

    這篇文章主要為大家介紹了go語言開發(fā)中如何優(yōu)雅得關(guān)閉協(xié)程方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • GO語言獲取系統(tǒng)環(huán)境變量的方法

    GO語言獲取系統(tǒng)環(huán)境變量的方法

    這篇文章主要介紹了GO語言獲取系統(tǒng)環(huán)境變量的方法,實例分析了Getenv方法操作環(huán)境變量的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • 一文了解Go語言io.Copy函數(shù)

    一文了解Go語言io.Copy函數(shù)

    這篇文章主要為大家介紹了Go語言io.Copy函數(shù)使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • Go 循環(huán)結(jié)構(gòu)for循環(huán)使用教程全面講解

    Go 循環(huán)結(jié)構(gòu)for循環(huán)使用教程全面講解

    這篇文章主要為大家介紹了Go 循環(huán)結(jié)構(gòu)for循環(huán)使用全面講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • Go語言開發(fā)編程規(guī)范命令風(fēng)格代碼格式

    Go語言開發(fā)編程規(guī)范命令風(fēng)格代碼格式

    這篇文章主要為大家介紹了Go語言開發(fā)編程規(guī)范命令風(fēng)格代碼格式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Go中的?=?和?:=?區(qū)別小結(jié)

    Go中的?=?和?:=?區(qū)別小結(jié)

    在Go語言編程中,"="用于給已聲明的變量賦值,而":="同時聲明并初始化變量,只能在函數(shù)內(nèi)使用,理解這兩者的不同,有助于編寫更清晰的代碼,下面就來介紹一下
    2024-10-10
  • 使用Go實現(xiàn)在命令行輸出好看的表格

    使用Go實現(xiàn)在命令行輸出好看的表格

    這篇文章主要介紹了使用Go實現(xiàn)在命令行輸出好看的表格方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Go語言O(shè)RM包中使用worm構(gòu)造查詢條件的實例詳解

    Go語言O(shè)RM包中使用worm構(gòu)造查詢條件的實例詳解

    worm是一款方便易用的Go語言O(shè)RM庫。worm支Model方式(持結(jié)構(gòu)體字段映射)、原生SQL以及SQLBuilder三種模式來操作數(shù)據(jù)庫,并且Model方式、原生SQL以及SQLBuilder可混合使用,本文通過一些例子來說明如何使用worm來構(gòu)造查詢條件,感興趣的朋友一起看看吧
    2022-07-07
  • 利用go語言實現(xiàn)查找二叉樹中的最大寬度

    利用go語言實現(xiàn)查找二叉樹中的最大寬度

    這篇文章主要介紹了利用go語言實現(xiàn)查找二叉樹中的最大寬度,文章圍繞主題展開詳細介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05

最新評論

东山县| 原阳县| 安宁市| 新丰县| 新津县| 长葛市| 盱眙县| 长汀县| 盱眙县| 巨鹿县| 页游| 望谟县| 福州市| 高陵县| 青州市| 买车| 麟游县| 宁河县| 浦县| 日喀则市| 巨野县| 雅安市| 阿克苏市| 灵丘县| 蛟河市| 鞍山市| 西充县| 共和县| 和静县| 连南| 定远县| 南丰县| 普陀区| 天水市| 宜黄县| 临西县| 商南县| 获嘉县| 桃园市| 辰溪县| 德化县|