写点什么

Go 学习笔记之 Channels

发布于: 3 小时前
Go 学习笔记之 Channels

如果说 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 statementx = <-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那一行。

发布于: 3 小时前阅读数: 3
用户头像

坚持分享接地气儿的架构技术文章! 2018.02.26 加入

同名微信公众号「架构精进之路」,专注软件架构研究,技术学习与职业成长!坚持原创总结、沉淀和分享,希望能带给大家一些引导和启发,感谢各位的支持(关注、点赞、分享)!

评论

发布
暂无评论
Go 学习笔记之 Channels