Go Channel應用:協程間信息同步
大家好,我是漁夫子。
今天給大家介紹的go channel的第二種應用:協程間同步信息。
通過channel,能夠確保一個協程在另一個協程完成工作之后才能繼續。如果需要在兩個或多個協程之間共享數據的場景中,這種用法就特別有用,并且能夠確保數據不會同時被多個協程修改非常重要。
我們先看一個簡單的示例:
package main
import (
"fmt"
"time"
)
func worker(done chan bool) {
fmt.Print("working...")
time.Sleep(time.Second)
fmt.Println("done")
done <- true
}
func main() {
done := make(chan bool, 1)
go worker(done)
<-done
}
在這個示例中,我們創建了一個worker協程,同時在main協程中創建了一個done通道。當worker協程完成工作后,往done通道中發送了一個true,代表通知main協程worker執行完畢了。
開源項目中的應用
接下來我們看幾個開源項目中的示例。
應用一:利用通道進行平滑關閉
在gin框架的example中,有一個關閉服務的示例,就是利用了通道來在兩個協程間進行通訊的特性。如下:
圖片
這里就是在main協程中創建了一個quit通道,然后并將該quit通道傳遞給signal.Notify函數,然后通過<-quit阻塞等待signal.Notify函數執行完畢。在signal.Notify中其實是注冊并監聽syscall.SIGTERM信號,通過啟動了一個新的協程來監聽該信號。當該信號發生時,就往quit通道中寫入一個os.Signal的數據。
應用二:fastcache中利用通道輸出結果
在fastcache開源項目中,有個功能是將數據保存到文件中。在保存函數中用到了并發保存,同時需要將每個保存的結果輸出。下面就是通過通道來接收每個協程的保存結果的功能。如下:
圖片
在上圖中,首先在save函數中初始化了一個results通道,然后將saveBuckets的結果輸出到results。在save函數的最下面,通過從results等待輸出每次saveBuckets的結果。你看,這里就是通過results通道將子協程中的結果輸出給save函數(父協程)了。
好了,今天通道的應用案例就分享到這里了。