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

GoLang channel使用介紹

 更新時間:2022年10月11日 10:29:36   作者:~龐貝  
Channel 和 goroutine 的結合是 Go 并發(fā)編程的大殺器。而 Channel 的實際應用也經常讓人眼前一亮,通過與 select,cancel,timer 等結合,它能實現各種各樣的功能。接下來,我們就要梳理一下 channel 的應用

停止信號

channel 用于停止信號的場景還是挺多的,經常是關閉某個 channel 或者向 channel 發(fā)送一個元素,使得接收 channel 的那一方獲知道此信息,進而做一些其他的操作。

任務定時

與 timer 結合,一般有兩種玩法:實現超時控制,實現定期執(zhí)行某個任務。

有時候,需要執(zhí)行某項操作,但又不想它耗費太長時間,上一個定時器就可以搞定:

select {
	case <-time.After(100 * time.Millisecond):
	case <-s.stopc:
		return false
}

等待 100 ms 后,如果 s.stopc 還沒有讀出數據或者被關閉,就直接結束。這是來自 etcd 源碼里的一個例子,這樣的寫法隨處可見。

定時執(zhí)行某個任務,也比較簡單:

func worker() {
	ticker := time.Tick(1 * time.Second)
	for {
		select {
		case <- ticker:
			// 執(zhí)行定時任務
			fmt.Println("執(zhí)行 1s 定時任務")
		}
	}
}

每隔 1 秒種,執(zhí)行一次定時任務。

解耦生產方和消費方

服務啟動時,啟動 n 個 worker,作為工作協程池,這些協程工作在一個 for {} 無限循環(huán)里,從某個 channel 消費工作任務并執(zhí)行:

func main() {
	taskCh := make(chan int, 100)
	go worker(taskCh)
    // 塞任務
	for i := 0; i < 10; i++ {
		taskCh <- i
	}
    // 等待 1 小時 
	select {
	case <-time.After(time.Hour):
	}
}
func worker(taskCh <-chan int) {
	const N = 5
	// 啟動 5 個工作協程
	for i := 0; i < N; i++ {
		go func(id int) {
			for {
				task := <- taskCh
				fmt.Printf("finish task: %d by worker %d\n", task, id)
				time.Sleep(time.Second)
			}
		}(i)
	}
}

5 個工作協程在不斷地從工作隊列里取任務,生產方只管往 channel 發(fā)送任務即可,解耦生產方和消費方。

finish task: 1 by worker 4
finish task: 2 by worker 2
finish task: 4 by worker 3
finish task: 3 by worker 1
finish task: 0 by worker 0
finish task: 6 by worker 0
finish task: 8 by worker 3
finish task: 9 by worker 1
finish task: 7 by worker 4
finish task: 5 by worker 2

控制并發(fā)數

有時需要定時執(zhí)行幾百個任務,例如每天定時按城市來執(zhí)行一些離線計算的任務。但是并發(fā)數又不能太高,因為任務執(zhí)行過程依賴第三方的一些資源,對請求的速率有限制。這時就可以通過 channel 來控制并發(fā)數。

下面的例子來自《Go 語言高級編程》:

var limit = make(chan int, 3)
func main() {
    // …………
    for _, w := range work {
        go func() {
            limit <- 1
            w()
            <-limit
        }()
    }
    // …………
}

構建一個緩沖型的 channel,容量為 3。接著遍歷任務列表,每個任務啟動一個 goroutine 去完成。真正執(zhí)行任務,訪問第三方的動作在 w() 中完成,在執(zhí)行 w() 之前,先要從 limit 中拿“許可證”,拿到許可證之后,才能執(zhí)行 w(),并且在執(zhí)行完任務,要將“許可證”歸還。這樣就可以控制同時運行的 goroutine 數。

這里,limit <- 1 放在 func 內部而不是外部,原因是:

如果在外層,就是控制系統 goroutine 的數量,可能會阻塞 for 循環(huán),影響業(yè)務邏輯。

limit 其實和邏輯無關,只是性能調優(yōu),放在內層和外層的語義不太一樣。

還有一點要注意的是,如果 w() 發(fā)生 panic,那“許可證”可能就還不回去了,因此需要使用 defer 來保證。

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

相關文章

  • go語言題解LeetCode1160拼寫單詞示例詳解

    go語言題解LeetCode1160拼寫單詞示例詳解

    這篇文章主要為大家介紹了go語言題解LeetCode1160拼寫單詞示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Golang常量iota的使用實例

    Golang常量iota的使用實例

    今天小編就為大家分享一篇關于Golang常量iota的使用實例,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 使用client-go工具調用kubernetes API接口的教程詳解(v1.17版本)

    使用client-go工具調用kubernetes API接口的教程詳解(v1.17版本)

    這篇文章主要介紹了使用client-go工具調kubernetes API接口(v1.17版本),本文通過圖文實例相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • 詳解Go語言如何實現一個最簡化的協程池

    詳解Go語言如何實現一個最簡化的協程池

    這篇文章主要為大家詳細介紹了Go語言如何實現一個最簡化的協程池,文中的示例代碼講解詳細,具有一定的參考價值,有需要的小伙伴可以了解一下
    2023-10-10
  • 為什么Go語言把類型聲明放在后面?

    為什么Go語言把類型聲明放在后面?

    今天小編就為大家分享一篇關于為什么Go語言把類型聲明放在后面?,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • GoFrame通用類型變量gvar與interface基本使用對比

    GoFrame通用類型變量gvar與interface基本使用對比

    這篇文章主要為大家介紹了GoFrame通用類型變量gvar與interface基本使用對比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 基于go微服務效率工具goctl深度解析

    基于go微服務效率工具goctl深度解析

    這篇文章主要為大家介紹了基于go微服務效率工具goctl深度解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • go的strings用法小結

    go的strings用法小結

    strings 是 Go 語言標準庫中提供的一個包,用于處理字符串相關的操作,本文主要介紹了go的strings用法小結,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • grpc入門Unary模式使用方法示例教程

    grpc入門Unary模式使用方法示例教程

    這篇文章主要為大家介紹了grpc入門Unary模式使用方法示例教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • 詳解Go?flag實現二級子命令的方法

    詳解Go?flag實現二級子命令的方法

    這篇文章主要介紹了Go?flag?詳解,實現二級子命令,本文就探討一下?Go?語言中如何寫一個擁有類似特性的命令行程序,需要的朋友可以參考下
    2022-07-07

最新評論

乌鲁木齐县| 深水埗区| 文化| 三原县| 无为县| 沿河| 尤溪县| 白山市| 津南区| 瑞丽市| 永平县| 广东省| 永德县| 隆安县| 巴彦淖尔市| 白城市| 循化| 如皋市| 克拉玛依市| 广元市| 蕲春县| 永州市| 内丘县| 元阳县| 社旗县| 连城县| 德钦县| 扬中市| 丹凤县| 南岸区| 宁夏| 澜沧| 无为县| 保山市| 东城区| 大余县| 西吉县| 香河县| 兴化市| 乐业县| 呼和浩特市|