环境
go version go1.10.1 darwin/amd64
Channels
信道是带有类型的管道,你可以通过它用信道操作符 <- 来发送或者接收值。
ch <- v // 将 v 发送至信道 ch。
v := <-ch // 从 ch 接收值并赋予 v。
("箭头"就是数据流的方向。)
和映射与切片一样,信道在使用前必须创建:
ch := make(chan int)
默认情况下,发送和接收操作在另一端准备好之前都会阻塞。这使得goroutines可以在没有显式的锁或竞态变量的情况下进行同步。以下示例对切片中的数进行求和,将任务分配给两个goroutines。 一旦两个goroutines完成了它们的计算,它就能算出最终的结果。
package main
import "fmt"
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // 将和送入 c
}
func main() {
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c // 从 c 中接收
fmt.Println(x, y, x+y)
}
运行后结果如下
-5 17 12
带缓冲的Channels
Channels可以是 带缓冲的,将缓冲长度作为第二个参数提供给 make 来初始化一个带缓冲的Channels:
ch := make(chan int, 100)
仅当Channels的缓冲区填满后,向其发送数据时才会阻塞。当缓冲区为空时,接受方会阻塞。修改示例填满缓冲区,然后看看会发生什么。
运行正常实例如下
package main
import "fmt"
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println(<-ch)
fmt.Println(<-ch)
}
运行后得到如下
1
2
运行异常的实例如下
package main
import "fmt"
func main() {
ch := make(chan int, 1)
ch <- 1
ch <- 2
fmt.Println(<-ch)
fmt.Println(<-ch)
}
运行后得到如下
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/Users/durban/go/src/github.com/durban.zhang/example/example.go:8 +0x73
exit status 2
版权声明
由 durban创作并维护的 小绒毛的足迹博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证。
本文首发于 博客( https://www.xiaorongmao.com ),版权所有,侵权必究。