共計 1621 個字符,預計需要花費 5 分鐘才能閱讀完成。
本篇文章為大家展示了 Go 無緩沖通道的陷阱是什么,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
定義
Channel 是 go 的特色之一,甚至說是最大的特色也不為過,使用起來也非常簡單。
首先定義一個 int 類型的 channel:
ch2 := make(chan int)
ch3 := make(chan int, 10)
我們這里主要關注無緩沖通道。
場景
來看看這段代碼:
package mainimport (
sync
fmt )func main() { wg := sync.WaitGroup{}
ch2 := make(chan int)
wg.Add(1)
for i := 0; i 10; i++ {
ch2 - i
}
go func1(ch2, wg)
wg.Wait()
close(ch2)
fmt.Println(Close channel: , ch2)
}func func1(ch chan int, wg *sync.WaitGroup) {
FOR:
for {
select {
case i, ok := - ch:
if !ok { fmt.Println( 1 chan closed, returning)
break FOR
} else { fmt.Println( 1 Got number: , i)
if i == 9 {
break FOR
}
}
default:
fmt.Println(1 Got nothing)
}
}
wg.Done()}
乍眼一看似乎沒毛病,但是當運行程序的時候:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/Users/bruce/Code/go/src/GoCommonServices/sync-demo/demo.go:19 +0xb9exit status 2Process finished with exit code 1
為什么呢?仔細看了看上面的程序,在定義了無緩沖通道 ch2 之后,立馬向其中寫入數據:
ch2 := make(chan int)
for i := 0; i 10; i++ {
ch2 - i
}
但此時并沒有消費者,而無緩沖通道在寫入一個數據之后,會等待消費者消費,程序阻塞,但啟動消費者的代碼:
go func1(ch2, wg)
恰好在 for 循環之后,所以這個 goroutine 永遠沒有啟動的機會,這就是報錯信息提示的,deadlock 了,要修復這個有兩種方法:
1 ch2 定義為緩沖通道,足夠容納 for 中的數據,就不會阻塞
ch2 := make(chan int, 10)
2 先啟動消費者,再向通道中寫數據
go func1(ch2, wg)
ch2 := make(chan int) for i := 0; i 10; i++ { ch2 - i }
歸根結底,還是因為 channel 的特性:
無緩沖的 channel,不管是入還是出,都會阻塞,所以在同一個 goroutine 中,不能同時對同一個無緩沖 channel 進行入和出操作;帶緩沖的 channel,在隊列滿之前,不會阻塞;隊列滿之后,依然會阻塞。go 是什么
golang 是一種編譯語言,可以將代碼編譯為機器代碼,編譯后的二進制文件可以直接部署到目標機器而無需額外的依賴,所以 golang 的性能優于其他的解釋性語言,且可以在 golang 中使用 goroutine 來實現并發性,它提供了一個非常優雅的 goroutine 調度程序系統,可以很容易地生成數百萬個 goroutine。
上述內容就是 Go 無緩沖通道的陷阱是什么,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注丸趣 TV 行業資訊頻道。