goroutine-stop
在 Go 的开源项目中, 经常能够看到通过关闭一个 stopc 的通道来退出 goroutine 的写法, 如下面这个例子
1 |
|
运行上面的程序会得到结果
1 |
|
可以看到,在执行两次的打印任务后,goroutine 都完成了退出。
为什么使用 close(stopc)
可以完成对两个 goroutine 的退出控制,而不是往 stopc 中发送两次数据呢?
在 go 语言的官方规格文档对 close 函数的说明中可以找到答案
For an argument
ch
with a core type that is a channel, the built-in functionclose
records that no more values will be sent on the channel. It is an error ifch
is a receive-only channel. Sending to or closing a closed channel causes a run-time panic. Closing the nil channel also causes a run-time panic. After callingclose
, and after any previously sent values have been received, receive operations will return the zero value for the channel’s type without blocking. The multi-valued receive operation returns a received value along with an indication of whether the channel is closed.
大意是当我们使用 close 关闭一个 channel 时,这标志着没有更多的数据发送到 channel 中了。当使用 close 关闭了一个 channel ,并且 channel 中的所有数据都被消费后,使用 <-
操作符从 channel 中读取数据时,将会返回 channel 数据类型的零值,并且不会被阻塞。
根据官方当我们使用 close 关闭了 stopc 后,goroutine 中的 select 作用域中的 stopc 分支将不会阻塞,直接返回零值。即使有多个消费者在监听,都将会返回零值,从而实现退出。
因此当需要控制多个 goroutine 的推出时,可以采用相同的方法,传入一个 stopc 的 channel,在需要退出时 close(stopc) 即可。