Golang Day5
Channel
- 可當不同 goroutine 的溝通管道
- 可當 buffer queue
簡單 Channel
package main
import(
"fmt"
)
var Message chan string
func Bot(){
msg := <- Message
fmt.Println(msg)
}
func main(){
Message =make(chan string)
go Bot()
Message <- "Hollo World"
}
Deadlock
- 當 Channel 沒有宣告 buffer 時,若 Sneder 端送出訊息,而此時 Reciver 還未收到,Sender 端會送不出第二則訊息,此時 Sender 會 block 住造成 Dealock
package main
import(
"fmt"
)
var Message chan string
func Bot(){
msg := <- Message
fmt.Println(msg)
}
func main(){
Message =make(chan string)
go Bot()
Message <- "Hollo World"
fmt.Println("first message finish")
Message <- "This is dangerous"
fmt.Println("second message finish")
}
如何避免 Deadlock
- 讓接收端不斷接收訊息,避免 main thread 卡死
- 宣告 Channel buffer
package main
import(
"fmt"
"time"
)
var Message chan string
func Bot(){
for msg:= range Message{
fmt.Println(msg)
}
}
func main(){
Message =make(chan string)
go Bot()
Message <- "Hollo World"
fmt.Println("first message finish")
Message <- "This is dangerous"
fmt.Println("second message finish")
time.Sleep(1 * time.Second) // 加入 Sleep 避免 Main thread 太快結束,看不到後面訊息
}
宣告 Channel Buffer
package main
import(
"fmt"
"time"
)
var Message chan string
func Bot(){
msg := <- Message
fmt.Println(msg)
}
func main(){
Message =make(chan string,5) //宣告 5 個 channel buffer,可以 queue 5 個 string
go Bot()
Message <- "Hollo World"
fmt.Println("first message finish")
Message <- "This is dangerous"
fmt.Println("second message finish")
}
Select
當有多個 Channel 要在同一線程控管輸出時可以使用,而決定誰輸出則是由 Golang 背後的演算法決定的;這概念相當於 C# 把 thread 丟進 thread pool 一樣是由系統控制的
package main
import(
"fmt"
)
var Sender1Channel chan string
var Sender2Channel chan string
func Sender1(){
Sender1Channel <- "this is channel one"
}
func Sender2(){
Sender2Channel <- "this is channel two"
}
func main(){
Sender1Channel =make(chan string)
Sender2Channel =make(chan string)
go Sender1()
go Sender2()
i:=0
for{
select{
case msg:=<-Sender1Channel:
fmt.Println(msg)
case msg:=<-Sender2Channel:
fmt.Println(msg)
}
i+=1
if i>=2{
break
}
}
}
0 意見