channel for go

Channel

channel 是 golang 中最核心的 feature 之一,因此理解 Channel 的原理对于学习和使用 golang 非常重要。
channel 是 goroutine 之间通信的一种方式,可以类比成 Unix 中的进程的通信方式管道。
channel 提供了一种通信机制,通过它,一个 goroutine 可以想另一 goroutine 发送消息。channel 本身还需关联了一个类型,也就是 channel 可以发送数据的类型。例如: 发送 int 类型消息的 channel 写作 chan int 。

channel 定义有缓存和无缓存 唯一区别在于数量控制阻塞

1
2
3
$ var nums chan bool
$ nums = make(chan bool) //设置无缓存通道
$ nums = make(chan bool ,3) //设置有缓存的通道

关闭 channel

golang 提供了内置的 close 函数对 channel 进行关闭操作
1
2
ch := make(chan int)
close(ch)

理解有缓存和无缓存区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

func main() {
maxNum := 3
limit := make(chan bool, maxNum) //缓存通道
quit := make(chan bool) //无缓存通道

for i := 0; i < 9; i++ {
limit <- true //缓存满3个 产生阻塞 执行下方的 gororutine
fmt.Println("start worker : ", i)
go func(i int) {
//执行这个gororutine 从代码上看这个gororutine不会阻塞
//保持这个gororutine 不会阻塞
fmt.Println("do worker start: ", i)
time.Sleep(time.Millisecond * 200)
fmt.Println("do worker finish: ", i)
res := <- limit // 取出一个chan limit缓存剩余2个,缓存通道开启,继续执行上面的 for 然后会在次阻塞,但是这个里面会继续执行
fmt.Println(res)
if i == 8 {
quit <- true //存入值 主程序获取到这个值 关闭主程序阻塞
fmt.Println("主程序退出")
}

}(i)
}

<-quit //chan读取数据一直读取不到 开启主程序阻塞
fmt.Println("收到退出通知,主程序退出")
}