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

Go中sync?包Cond使用場景分析

 更新時間:2023年03月03日 14:50:04   作者:水淹萌龍  
Cond?是和某個條件相關,在條件還沒有滿足的時候,所有等待這個條件的協(xié)程都會被阻塞住,只有這個條件滿足的時候,等待的協(xié)程才可能繼續(xù)進行下去,這篇文章主要介紹了Go中sync?包的Cond使用場景分析,需要的朋友可以參考下

背景

編寫代碼過程中, 通常有主協(xié)程和多個子協(xié)程進行協(xié)作的過程,比如通過 WaitGroup 可以實現(xiàn)當所有子協(xié)程完成之后, 主協(xié)程再繼續(xù)執(zhí)行, 具體可參考:Go 中goroutine和WaitGroup的使用

如上的場景是主協(xié)程等待子協(xié)程達到某個狀態(tài)再繼續(xù)運行。 但是反過來怎么操作呢,要求一組子協(xié)程等待主協(xié)達到某個狀態(tài)時才繼續(xù)運行。這個時候就需要用到 Cond 了

Cond 簡介

Cond 是和某個條件相關,在條件還沒有滿足的時候,所有等待這個條件的協(xié)程都會被阻塞住,只有這個條件滿足的時候,等待的協(xié)程才可能繼續(xù)進行下去。
Cond 在初始化的時候,需要關聯(lián)一個 Locker 接口的實例,一般會使用 Mutex 或者 RWMutex。
Cond 關聯(lián)的 Locker 實例可以通過 c.L 訪問,它內部維護著一個先入先出的等待隊列。
Cond 分別有三個方法

  • Wait

會把當前協(xié)程放入Cond的等待隊列中并阻塞,直到被Signal或者Broadcast方法從等待隊列中移除并喚醒,用于子協(xié)程阻塞。

  • Signal

主協(xié)程喚醒等待隊列中的一個子協(xié)程,先喚醒最先阻塞的子協(xié)程,被喚醒的子協(xié)程繼續(xù)執(zhí)行。

  • Broadcast

主協(xié)程喚醒等待隊列中的全部協(xié)程,所有子協(xié)程繼續(xù)執(zhí)行。

注意:調用Signal和Broadcast方法,不強求持有c.L的鎖,調用Wait方法是必須要持有c.L的鎖。

使用示例

Signal的使用場景

大家都去醫(yī)院先排隊,然后等待叫號,先排隊的先叫號。這次模擬有5個病人,分別先排隊。 然后護士根據(jù)排隊先后來叫號;
具體場景是,5個病人在三秒中之內分別排號,護士今天要叫5個號,一秒叫一個,叫完5個號就結束了
代碼如下:

package main
import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

func main() {
	c := sync.NewCond(&sync.Mutex{})
	num := 0
	// 當前叫號是幾號
	hand_num := 0
	for i := 0; i < 5; i++ {
		go func(i int) {
			// 分別在不同時間排隊
			time.Sleep(time.Second * time.Duration(rand.Int63n(10)))
			c.L.Lock()
			num++
			// 當前取得號。
			cur := num
			fmt.Printf("%s  %d 號病人取到了 %d 號\n", time.Now().Format("2006-01-02 15:04:05"), i, cur)
			// 取到號了,等待叫號
			c.Wait()
			fmt.Printf("%s  %d 號病人排隊號是 %d 號,被叫號了\n", time.Now().Format("2006-01-02 15:04:05"), i, cur)
			hand_num = cur
			c.L.Unlock()
		}(i)
	}

	// 都叫號了
	for hand_num != 5 {
		// 叫號
		c.Signal()
		time.Sleep(time.Second * 1)
	}

	time.Sleep(time.Second * 10)
}

執(zhí)行結果如下

在這里插入圖片描述

結果表明,5個病人,分別在三秒鐘內先后取號, 然后護士每過一秒鐘按照排隊的先后順序叫一個號(叫號的過程依然有病人取號),先取號的被先叫號。
此場景中,5個病人相當于5個協(xié)程, 主協(xié)程反復使用Signal() 按照順序一個個喚醒阻塞的子協(xié)程。

Broadcast的使用場景

場景為如下: 運動員跑步比賽,要求8秒內全部運動員準備好,然后等待教練發(fā)令, 教練10秒后發(fā)令,所有運動員在發(fā)令后開始跑。

package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

func main() {
	c := sync.NewCond(&sync.Mutex{})

	for i := 0; i < 10; i++ {
		go func(i int) {
			// 隨機一個8秒內的準備時間
			time.Sleep(time.Second * time.Duration(rand.Int63n(8)))
			fmt.Printf("%s 運動員%d已準備就緒\n", time.Now().Format("2006-01-02 15:04:05"), i)
			c.L.Lock()
			// 準備完畢,等待教練發(fā)令
			c.Wait()
			c.L.Unlock()
			fmt.Printf("%s 運動員%d開跑\n", time.Now().Format("2006-01-02 15:04:05"), i)
		}(i)
	}

	// 主協(xié)程等待10秒后發(fā)令
	time.Sleep(time.Second * 10)
	fmt.Printf("%s 教練發(fā)令。\n", time.Now().Format("2006-01-02 15:04:05"))
	// 教練發(fā)令。通知所有運動員開始跑步, 即喚起之前 wait()的所有協(xié)程
	c.Broadcast()
	// 等待跑步
	time.Sleep(time.Second * 5)
}

執(zhí)行結果如下:

如結果所示, 10個運動員在8秒內分別準備好,等待教練發(fā)令后,同時開跑。
此場景中,10個運動員相當于10個協(xié)程, 同時等待主協(xié)程的命令,使用Broadcast() 喚醒所有阻塞的子協(xié)程。

注意事項

使用 Cond,最容易踩的坑就是調用 Wait() 方法之前,調用者沒有持有鎖或沒有檢查輔助條件。
在如上示例代碼中,假如把調用 Wait() 方法前后的加鎖和釋放鎖的代碼注釋掉,運行代碼會導致程序 panic。原因是調用 Wait 方法,會先把調用者放入等待隊列中,然后釋放鎖。此時如果在未持有鎖時調用釋放鎖的方法,就會導致程序 panic。

到此這篇關于Go中sync 包的 Cond 使用的文章就介紹到這了,更多相關go sync包cond使用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Go語言如何實現(xiàn)將[][]byte轉為io.Reader

    Go語言如何實現(xiàn)將[][]byte轉為io.Reader

    本文主要介紹了如何在Go語言中實現(xiàn)將[][]byte轉換為io.Reader,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2025-02-02
  • 淺談Go連接池的設計與實現(xiàn)

    淺談Go連接池的設計與實現(xiàn)

    本文主要介紹了淺談Go連接池的設計與實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • 一文帶你了解Go語言中的I/O接口設計

    一文帶你了解Go語言中的I/O接口設計

    I/O?操作在編程中扮演著至關重要的角色,它涉及程序與外部世界之間的數(shù)據(jù)交換,下面我們就來簡單了解一下Go語言中的?I/O?接口設計吧
    2023-06-06
  • 解決Golang在Web開發(fā)時前端莫名出現(xiàn)的空白換行

    解決Golang在Web開發(fā)時前端莫名出現(xiàn)的空白換行

    最近在使用Go語言開發(fā)Web時,在前端莫名出現(xiàn)了空白換行,找了網(wǎng)上的一些資料終于找到了解決方法,現(xiàn)在分享給大家,有需要的可以參考。
    2016-08-08
  • Go語言error的設計理念及背景演化詳解

    Go語言error的設計理念及背景演化詳解

    這篇文章主要為大家介紹了Go語言error的設計理念及背景演化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • go語言實現(xiàn)AES加密的方法

    go語言實現(xiàn)AES加密的方法

    這篇文章主要介紹了go語言實現(xiàn)AES加密的方法,實例分析了Go語言的加密技巧,需要的朋友可以參考下
    2015-03-03
  • golang如何去除 context 的 deadline

    golang如何去除 context 的 deadline

    在使用 context 的時候遇到了開協(xié)程處理任務的情況,但是直接在協(xié)程里使用主線程的 context 會導致當主線程返回時協(xié)程任務也會因為 context cancel 而失敗,本文提供了兩種辦法可以取消掉 context 里的 timeout 和 deadline,再設置一個新的 timeout 上去
    2023-03-03
  • 一文帶你吃透Golang中net/http標準庫服務端

    一文帶你吃透Golang中net/http標準庫服務端

    這篇文章將從服務端(Server)作為切入點和大家分享一下Go語言net/http標準庫的實現(xiàn)邏輯,進而一步步分析http標準庫內部是如何運作的,感興趣的可以了解下
    2024-03-03
  • Golang庫插件注冊加載機制的問題

    Golang庫插件注冊加載機制的問題

    這篇文章主要介紹了Golang庫插件注冊加載機制,這里說的插件并不是指的golang原生的可以在buildmode中加載指定so文件的那種加載機制,需要的朋友可以參考下
    2022-03-03
  • Golang發(fā)送http GET請求的示例代碼

    Golang發(fā)送http GET請求的示例代碼

    這篇文章主要介紹了Golang發(fā)送http GET請求的示例代碼,幫助大家更好的理解和使用golang,感興趣的朋友可以了解下
    2020-12-12

最新評論

岳阳县| 共和县| 阜南县| 哈尔滨市| 开原市| 渝北区| 淳化县| 浦城县| 镇原县| 临潭县| 三台县| 晋宁县| 阳曲县| 潜江市| 离岛区| 麻阳| 天峻县| 麻栗坡县| 黑龙江省| 林甸县| 桦甸市| 皋兰县| 洱源县| 江口县| 京山县| 融水| 信阳市| 和田县| 永泰县| 古丈县| 海原县| 漠河县| 祁阳县| 潮州市| 石嘴山市| 静安区| 全椒县| 梁平县| 察雅县| 博湖县| 庆阳市|