chan / 通道
go
// 定义通道
messages := make(chan string)
// 发
go func() { messages <- "ping" }()
// 接收
msg := <-messages缓冲通道
go
messages := make(chan string, 2)只写 && 只写
https://gobyexample-cn.github.io/channel-directions
chan int // 双向
<-chan int // 只读
chan<- int // 只写主要是通过“变量类型”实现的,但不只是
go
ch := make(chan int)
var readOnly <-chan int = ch
var writeOnly chan<- int = ch遍历通道
go
queue := make(chan string, 2)
queue <- "one"
queue <- "two"
close(queue) // 没有 close 会一直卡住
for elem := range queue {
fmt.Println(elem)
}channel 关闭且缓冲已空,会直接结束
超时
time.After
触发超时
go
c1 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c1 <- "result 1"
}()
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(1 * time.Second):
fmt.Println("timeout 1")
}未触发超时
go
c2 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c2 <- "result 2"
}()
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(3 * time.Second):
fmt.Println("timeout 2")
}关闭通道
close 的含义是 “不会再有新的数据发送了”
go
jobs := make(chan int, 5)
close(jobs)close 只是标记 channel 为“已关闭”, 不是销毁,不是清空,也不是立刻释放内存。
close 做了三件事:
- 标记 channel 状态为 closed
- 唤醒所有正在等待接收的 goroutine
- 后续再写入会 panic
go
v, ok := <-jobs
// ok == false 已经关闭 且 无数据已经关闭,且无值,读空后得到零值
通道同步
https://gobyexample-cn.github.io/channel-synchronization
本质是利用通道的堵塞功能
go
func worker(done chan bool) {
fmt.Print("working...")
time.Sleep(time.Second)
fmt.Println("done")
done <- true
}
func main() {
done := make(chan bool, 1)
go worker(done)
<-done
}