go語言通道
阿新 • • 發佈:2018-12-24
注意
:通道首先要通過make函式來初始化,初始化之後才可以執行寫入和讀取操作。此外還分為【有快取通道
】和【無快取通道
】,make函式第二個引數大於1,表示有快取;make函式的第二個引數的型別為整型,在使用make函式初始化通道時,快取必須大於1。不可以是0。
首先看一下通道在一個協程中的例子
傳送操作阻塞
package main
func main() {
var ch chan struct{}
//ch = make(chan struct{}, 1)
ch <- struct{}{}
<-ch
}
執行結果
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send (nil chan)]:
main.main()
傳送(寫入)操作阻塞,此外通道沒有初始化,nil chan
表示通道沒有初始化。
接收操作阻塞
package main
func main() {
var ch chan struct{}
ch = make(chan struct{}, 1)
<-ch //程式到這一行直接阻塞,即使有快取也不行,因為通道為空,讀不到資料。
ch <- struct{}{}
}
執行結果
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
讀取(接收)操作阻塞,即使有快取也會繼續阻塞,因為通道為空,讀取不到資料,後面的程式碼不會執行了。
編譯通過
package main
func main() {
var ch chan struct{}
ch = make(chan struct{}, 1)
ch <- struct{}{}
<-ch
}
因為有快取,所以可以往通道里寫入資料,即使把最後一行註釋掉,程式也可以正常執行,不會阻塞。
分別在兩個協程中進行讀取(接收)和寫入(傳送),一邊讀取,一邊寫入
讀取寫入均阻塞
package main
func main() {
var ch chan struct{}
go func() {
ch <- struct{}{}
}()
<-ch
}
執行結果
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive (nil chan)]:
main.main()
goroutine 4 [chan send (nil chan)]:
main.main.func1(0x0)
created by main.main
雖然程式可以一直執行到最後一行,但是因為通道沒有初始化,所以兩邊都阻塞。
接收操作阻塞
package main
func main() {
var ch chan struct{}
ch = make(chan struct{})
<-ch
go func() {
ch <- struct{}{}
}()
}
執行結果
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
主函式接收操作首先阻塞,後面的程式碼不會執行了,即使通道有快取也會阻塞,因為通道為空,讀取不到資料。
傳送和接收均阻塞
package main
func main() {
var ch chan struct{}
go func() {
<-ch
}()
ch <- struct{}{} //程式一直可以執行到這一行,但是通道沒有初始化,所以兩邊都阻塞。
}
執行結果
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send (nil chan)]:
main.main()
goroutine 17 [chan receive (nil chan)]:
main.main.func1(0x0)
created by main.main
雖然程式一直可以執行到最後一行,但是因為通道沒有初始化,所以兩邊都阻塞,這個例子是主函式裡邊寫入,子協程裡邊讀取,與上一個兩邊均阻塞的正好反過來。
傳送操作阻塞
package main
func main() {
var ch chan struct{}
ch = make(chan struct{})
ch <- struct{}{} //函式執行到這一行直接阻塞,不管有無快取,都會阻塞
go func() {
<-ch
}()
}
執行結果
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
主函式傳送(寫入)操作先阻塞了,後面的程式碼不會執行了,不管通道有無快取,程式都已經阻塞不會再繼續往下執行了。
另一個協程準備好了接收資料
package main
func main() {
var ch chan struct{}
ch = make(chan struct{})
go func() {
<-ch
}()
ch <- struct{}{} //因為另一個協程已經準備好了接收,所以通道無快取,程式也可以執行
}
因為另一個協程準備好了讀取資料,所以即使通道無快取也可以正常執行。
另一個協程往通道中寫入了資料
package main
func main() {
var ch chan struct{}
ch = make(chan struct{})
go func() {
ch <- struct{}{}
}()
<-ch //程式一直可以執行到這一行,而另一個協程準備好了往通道里寫入了資料,所以即使通道無快取,也可以正常執行。
}
因為另一個協程已經準備好了往通道里寫入資料,所以通道無快取也不會阻塞。