go 社区有一句口号:”不要通过共享内存来通信,而应该通过通信来共享内存”, channel 用于 goroutine 之间传递消息。如果是多进程之间的通信,还是推荐使用 socket 或者 http.
channel 操作
声明和定义
channel 只能发送指定类型的数据,因此channel的声明和定义必须指定类型;
1 | // 声明一个 int类型的 channel |
channel 的缓存
从无缓存的 channel 中读取消息,会发生阻塞,直到有 goroutine 向该channel 发送消息;同理向无缓存的channle发送消息也会阻塞,直到有 goroutine 读取该channel中的消息。
通过无缓存的channel进行通信时,接受者收到数据 happens before 发送者 goroutine 唤醒
有缓存的 channel 当缓存未满时,发送消息不会阻塞,当缓存慢时,发送消息会阻塞。当缓存不为空时,读取消息不会阻塞,缓存为空时,读取消息会阻塞。
许式伟《go语言编程》中关于 channel 的例子有点小问题,如果是等待 gorotine 完成,建议把写 channel 的操作放在函数的最后,避免 channel 刚写完,就被读取,而其它部分代码还没执行就退出了。
channel 数据发送和读取
1 | // 写入数据 |
还可以使用 range 来读取 channel
1 | ch := make(chan int, 10) |
range 会一直从 channel 中取值,直到有 goroutine 对该 channel 调用 close 操作。上面的代码等价于:
1 | for { |