Go劍復國-30天導入Golang Day12 Golang channel
接下來是 golang 重頭戲之二 channel ,上一篇已經有講過 gorotuine,channel 的用途非常多,可以拿來當不同 gorotuine 的溝通通道,也可以 buffer quene,那接下來開始介紹 channel
channel
首先我們要先來試試看,如何宣告一個 channel,並且傳送一個訊息給它
package main
import (
"fmt"
)
var message chan string
func Bot() {
msg := <-message
fmt.Printf("Bot Print:%s\n", msg)
}
func main() {
message = make(chan string)
go Bot()
message <- "Hello World"
fmt.Println("end")
}
https://play.golang.org/p/kdVCn2Abk11
channel 如果沒有宣告 buffer, sender 端,送進去的訊息,reciver 端沒收之前,sender 端送不進去第二則訊息,此時,sender 端會 block,在這邊要注意控制這個問題,以避免造成 deadlock。
下面我們示範一下 deadlock 情境
package main
import (
"fmt"
)
var message chan string
func Bot() {
msg := <-message
fmt.Printf("Bot Print:%s\n", msg)
}
func main() {
message = make(chan string)
go Bot()
message <- "first message"
fmt.Println("first message send finish")
message <- "second message"
fmt.Println("second message send finish")
fmt.Println("end")
}
https://play.golang.org/p/O_DjamN8sss
那如何在沒宣告 buffer 的情況下,排除上面的 deadlock
package main
import (
"fmt"
"time"
)
var message chan string
func Bot() {
//讓bot 不斷接收訊息,就不會造成 main thread 卡死
for msg := range message {
fmt.Printf("Bot Print:%s\n", msg)
}
}
func main() {
message = make(chan string)
go Bot()
message <- "first message"
fmt.Println("first message send finish")
message <- "second message"
fmt.Println("second message send finish")
//加入Sleep 是為了避免 main thread提前結束,而看不到 bot 後續印的值
time.Sleep(1*time.Second)
fmt.Println("end")
}
https://play.golang.org/p/OSzlVjXGMIj
那如何宣告 channel 的 buffer 呢?
package main
import (
"fmt"
)
var message chan string
func Bot() {
msg := <-message
fmt.Printf("Bot Print:%s\n", msg)
}
func main() {
//這裡為宣告 5 個 channel buffer,意思就是可以quene 5個 string
message = make(chan string, 5)
go Bot()
message <- "first message"
fmt.Println("first message send finish")
message <- "second message"
fmt.Println("second message send finish")
fmt.Println("end")
}
https://play.golang.org/p/NpBkrnKGfIQ
由上面可以看到,運用 buffer 宣告也可以解決前面範例 deadlock 的問題。
Do not communicate by sharing memory; instead, share memory by communicating.
上面這句話,是引言自,golang 官方 blog,有一篇講解 channel 的使用時機、跟他的設計精神,有興趣的可以前往閱讀。