概述
建議先閱讀 goroutine 小節,
Go 箴言: 不要通過共享記憶體來通信,而要通過通信來共享記憶體,
goroutine 是 Go 程式并發執行的物體,channel (通道) 則是它們之間的連接,用于多個 goroutine 之間互相通信,通道可以讓一個 goroutine 發送特定型別值到另一個 goroutine,每一個通道可以發送資料型別稱為通道的 元素型別,
阻塞通道與非阻塞通道
通過關鍵字 chan + 資料型別 來表明通道資料型別,呼叫 make() 函式來初始化一個通道, make() 函式的第二個引數為通道長度,如果未指定或指定為 0,則該通道為非快取通道 (阻塞通道), 否則該通道為快取通道 (非阻塞通道),
阻塞通道
圖片來源: https://stackoverflow.com/questions/39826692/what-are-channels-used-for
例子
ch := make(chan string) // 非緩沖通道
ch := make(chan string, 0) // 非緩沖通道
ch := make(chan string, 10) // 緩沖通道, 容量為 10
3 種操作
發送
無緩沖通道上面的發送操作將會阻塞,直到另一個 goroutine 在對應的通道上面完成接收操作,兩個 goroutine 才可以繼續執行,
語法規則
通道變數 <- 資料
# 例如: 將變數 x 發送到通道 ch
ch <- x
接收
無緩沖通道上面的接收操作將會阻塞,直到另一個 goroutine 在對應的通道上面完成發送操作,兩個 goroutine 才可以繼續執行,
語法規則
<- 通道變數
# 例如: 從通道 ch 接收一個值,并且丟棄
<-ch
接收變數 <- 通道變數
# 例如: 從通道 ch 接收一個值,并且賦值給變數 x
x := <-ch
關閉
詳情見 關閉通道,
例子
搭配 goroutine
package main
func main() {
ch := make(chan string) // 沒有設定通道的長度
go func() {
ch <- "hello world"
}()
msg := <-ch // 一直阻塞,直到接收到通道訊息
println(msg)
}
// $ go run main.go
// 輸出如下
/**
hello world
*/
死鎖
package main
func main() {
ch := make(chan string) // 沒有設定通道的長度
ch <- "hello world" // 向通道發送資料,但是沒有接收者
msg := <-ch // 代碼執行不到這里, 因為上面阻塞發送資料時,就已經死鎖了
println(msg)
}
// $ go run main.go
// 輸出如下
/**
fatal error: all goroutines are asleep - deadlock!
...
...
exit status 2
*/
非阻塞通道
圖片來源: https://stackoverflow.com/questions/39826692/what-are-channels-used-for
例子
ch := make(chan string, 10) // 緩沖通道, 容量為 10
3 種操作
發送
-
? 如果通道已滿 (元素數量達到容量), 發送操作將會阻塞,直到另一個
goroutine在對應的通道上面完成接收操作, 兩個goroutine才可以繼續執行 -
? 如果通道未滿,發送操作不會阻塞
語法規則
通道變數 <- 資料
# 例如: 將變數 x 發送到通道 ch
ch <- x
接收
-
? 如果通道已空 (元素數量為 0),接收操作將會阻塞,直到另一個
goroutine在對應的通道上面完成發送操作, 兩個goroutine才可以繼續執行 -
? 如果通道不為空,接收操作不會阻塞
語法規則
<- 通道變數
# 例如: 從通道 ch 接收一個值,并且丟棄
<-ch
接收變數 <- 通道變數
# 例如: 從通道 ch 接收一個值,并且賦值給變數 x
x := <-ch
關閉
詳情見 關閉通道,
例子
快取通道容量為 2
package main
func main() {
ch := make(chan string, 2)
ch <- "hello" // 不會死鎖,因為 ch 是緩沖通道
ch <- "world"
println(<-ch)
println(<-ch)
}
// $ go run main.go
// 輸出如下
/**
hello
world
*/
擴展閱讀
====
- 1. 死鎖 - 維基百科
聯系我

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/540573.html
標籤:Go
