8.8. Channels(管道)
管道可以用于两个goroutines之间的通讯。我们可以用管道传递任意类脂的变量。Go语言中管道是 廉价并且便捷的。 二元操作符 <- 用于向管道发送数据。一元操作符<- 用于从管道接收数据。在函数参数中,管道通过引用传递给函数。
虽然go语言的标准库中提供了互斥的支持,但是我们也可以用一个单一的goroutine提供对变量的 共享操作。 例如,下面的函数用于管理对变量的读写操作。
type cmd struct { get bool; val int }
func manager(ch chan cmd) {
var val int = 0
for {
c := <- ch
if c.get { c.val = val ch <- c }
else { val = c.val }
}
}
在这个例子中,管道被同时用于输入和输出。但是当多个goroutines对变量操作时可能导致 问题:对管道的读操作可能读到的是请求命令。解决的方法是将命令和数据分为不同的管道。
type cmd2 struct { get bool; val int; ch <- chan int }
func manager2(ch chan cmd2) {
var val int = 0
for {
c := <- ch
if c.get { c.ch <- val }
else { val = c.val }
}
}
这里掩饰了如何使用manager2:
func f4(ch <- chan cmd2) int {
myCh := make(chan int)
c := cmd2{ true, 0, myCh } // Composite literal syntax.
ch <- c
return <-myCh
}