基础知识
Golang中的Channel是一个类似于管道的类型,我们可以通过Channel来在不同的Goroutine之间传递数据。
创建Channel:ch := make(chan int)
或 ch := make(chan int, 10)
前者是不带缓冲区的Channel,后者是带缓冲区的Channel。区别在于不带缓冲区的Channel在Send操作后会一直阻塞直到数据被Receive,而带缓冲区的Channel在缓冲区被填满之前都不会阻塞
Send操作:ch <- 1
Receive操作:i := <-ch
关闭操作:close(ch)
Tip1:关闭后Channel的行为
在Channel被执行关闭操作后,继续执行Send操作会导致panic: send on closed channel
,而继续执行Receive操作还可以读到Channel中的数据,所有数据读取完后会不断地读到该类型默认初始化的值(如果类型为int则读到0,类型为bool则读到false)。
Tip2:控制退出
该Channel所在的Goroutine在另一个Goroutine执行quit <- true
时退出。1
2
3
4
5
6
7
8for {
select {
case x := <-ch:
doSomething()
case <-quit:
quit()
}
}
Tip3:控制超时
该Channel所在的Goroutine在等待时间t后ch仍然未接收到数据时退出。1
2
3
4
5
6
7
8for {
select {
case x := <-ch:
doSomething()
case <-time.After(t):
timeout()
}
}
Tip4:清空缓冲区
假如ch中已经有数据了,可以使用下面的代码来清空缓冲区。如果ch中没有数据则直接执行后面的代码。1
2
3
4select {
case <-ch:
default:
}
Tip5:定时器
下面的代码会阻塞当前Goroutine一秒。1
2t := time.NewTimer(time.Second)
<-t.C
还可以使用t.Stop()
操作来停止这个定时器。