小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文同时参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金
如果说 goroutine 是 Go 语言程序的并发体的话,那么 channels 则是它们之间的通信机制。
一个 channel 是一个通信机制,它可以让一个 goroutine 通过它给另一个 goroutine 发送值信息。每个 channel 都有一个特殊的类型,也就是 channels 可发送数据的类型。
一个可以发送 int 类型数据的 channel 一般写为 chan int。
channel 创建
// 使用内置make函数,我们可以创建一个channel
ch := make(chan int) // ch has type 'chan int'
和 map 类似,channel 也对应一个 make 创建的底层数据结构的引用。
当我们复制一个 channel 或用于函数参数传递时,我们只是拷贝了一个 channel 引用,因此调用者和被调用者将引用同一个 channel 对象。和其它的引用类型一样,channel 的零值也是 nil。
Channel 应用
一个 channel 有发送和接受两个主要操作,都是通信行为,你可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication)。
一个发送语句将一个值从一个 goroutine 通过 channel 发送到另一个执行接收操作的 goroutine。发送和接收两个操作都使用<-运算符。在发送语句中,<-运算符分割 channel 和要发送的值。在接收语句中,<-运算符写在 channel 对象之前。一个不使用接收结果的接收操作也是合法的。
ch <- x // a send statement
x = <-ch // a receive expression in an assignment statement
<-ch // a receive statement; result is discarded
Channel 关闭
Channel 还支持 close 操作,用于关闭 channel,随后对基于该 channel 的任何发送操作都将导致 panic 异常。
-
对一个已经被 close 过的 channel 进行接收操作依然可以接受到之前已经成功发送的数据;
-
如果 channel 中已经没有数据的话将产生一个零值的数据。
// 使用内置的close函数就可以关闭一个channel close(ch)
Channel 处理
for …… range语句可以处理 Channel。
func main() {
go func() {
time.Sleep(1 * time.Hour)
}()
c := make(chan int)
go func() {
for i := 0; i < 10; i = i + 1 {
c <- i
}
close(c)
}()
for i := range c {
fmt.Println(i)
}
fmt.Println("Finished")
}
range c产生的迭代值为 Channel 中发送的值,它会一直迭代直到 channel 被关闭。上面的例子中如果把close(c)注释掉,程序会一直阻塞在for …… range那一行。
- END -
作者:架构精进之路,十年研发风雨路,大厂架构师,CSDN 博客专家,专注架构技术沉淀学习及分享,职业与认知升级,坚持分享接地气儿的干货文章,期待与你一起成长。
关注并私信我回复“01”,送你一份程序员成长进阶大礼包,欢迎勾搭。
Thanks for reading!