Go 使用channel控制併發

1. 前言

channel通常用於協程之間的通訊,channel也能夠用於併發控制。好比主協程啓動N個子協程,主協程等待全部子協程退出後再繼續後續流程,這種場景下channel也可輕易實現。git

2. 場景示例

下面程序展現一個使用channel控制子協程的例子:github

package main

import (
    "time"
    "fmt"
)

func Process(ch chan int) {
    //Do some work...
    time.Sleep(time.Second)

    ch <- 1 //管道中寫入一個元素表示當前協程已結束
}

func main() {
    channels := make([]chan int, 10) //建立一個10個元素的切片,元素類型爲channel

    for i:= 0; i < 10; i++ {
        channels[i] = make(chan int) //切片中放入一個channel
        go Process(channels[i])      //啓動協程,傳一個管道用於通訊
    }

    for i, ch := range channels {  //遍歷切片,等待子協程結束
        <-ch
        fmt.Println("Routine ", i, " quit!")
    }
}

上面程序經過建立N個channel來管理N個協程,每一個協程都有一個channel用於跟父協程通訊,父協程建立完全部協程中等待全部協程結束。併發

這個例子中,父協程僅僅是等待子協程結束,其實父協程也能夠向管道中寫入數據通知子協程結束,這時子協程須要按期的探測管道中是否有消息出現。ui

3. 總結

使用channel來控制子協程的優勢是實現簡單,缺點是當須要大量建立協程時就須要有相同數量的channel,並且對於子協程繼續派生出來的協程不方便控制。code

後面繼續介紹的WaitGroup、Context看起來比channel優雅一些,在各類開源組件中使用頻率比channel高得多。協程

贈人玫瑰手留餘香,若是以爲不錯請給個贊~get

本篇文章已歸檔到GitHub項目,求星~ 點我即達it

相關文章
相關標籤/搜索