1.通道简介
通道(channel)是用来传递数据的一个数据结构。通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <-
用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。
2.两种通道
- 无缓存的通道(unbuffered channel):是指在接收前没有能力保存任何值的通道,这种类型的通道要求发送goroutine和接收goroutine同时准备好,才能完成发送和接收操作。如果两个goroutine没有同时准备好,通道会导致先执行发送或接收操作的goroutine阻塞等待。
- 有缓存的通道:带缓冲区的通道允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。不过由于缓冲区的大小是有限的,所以还是必须有接收端来接收数据的,否则缓冲区一满,数据发送端就无法再发送数据了。
注意:如果通道不带缓冲,发送方会阻塞直到接收方从通道中接收了值。如果通道带缓冲,发送方则会阻塞直到发送的值被拷贝到缓冲区内;如果缓冲区已满,则意味着需要等待直到某个接收方获取到一个值。接收方在有值可以接收之前会一直阻塞。
向通道发送值或者指针 使用 chan <- data
从通道读数据 data:=<-chan
ex1 通道不缓冲,发送方发送信息,接收不接收,阻塞代码:
ex2 通道缓冲, 发送方发送消息, 接收方不接收消息,代码不阻塞:
ex3: 通道不缓存,发送方发送消息,接收方接收消息,代码正常运行:
ps: 代码只是学习代码,因此没有考虑正常关闭channel之类的操作,说到这个,提一句,通过关闭后close(channel),goroutine依旧可以从通道接收数据,但是不能再向通道发送数据。这一点很重要,带缓存的通道可以再通道关闭之后依旧可以保证取出缓存中所有的数据,而不会有数据丢失。从一个已经关闭且没有数据的通道里获取数据,总会立刻返回,并返回一个通道类型的零值。如果在获取通道的时候还加入了可选的标志,就能得到通道的状态信息。
向大佬请教: 本人之前写java, 以为这边的阻塞效果会是代码一直在运行,然后阻塞在12行的输出,但是go直接报错的,
这里希望有知道的大佬指教一下。感觉是go的语言处理机制。
本人近期刚学go,写博客纯属于记笔记,若有理解有误的地方还请大牛不吝赐教,谢谢。