golang chan 关闭时的原则
(金庆的专栏 2020.1)
golang 程序中检测到 DATA RACE, 是 chan 关闭和发送冲突:
<pre><code>================== WARNING: DATA RACE Write at 0x00c000098010 by goroutine 68: runtime.closechan() /usr/lib/golang/src/runtime/chan.go:327 0x0 valky/common/tcp.(*Session).Close() /var/tmp/src/f4f4f712-7894-4d98-83dd... valky/common/tcp.(*Session).recvloop() /var/tmp/src/f4f4f712-7894-4d98-83dd... Previous read at 0x00c000098010 by goroutine 100: runtime.chansend() /usr/lib/golang/src/runtime/chan.go:140 0x0 valky/common/tcp.(*Session).Send() /var/tmp/src/f4f4f712-7894-4d98-83dd... main.(*Role).sendMsg() /var/tmp/src/f4f4f712-7894-4d98-83dd... ================== Found 1 data race(s) </code></pre>查了一下 chan 关闭的正确做法,发现了一篇非常详细的文章:
How to Gracefully Close Channels
文中指出,chan 多次关闭,或者在关闭的 chan 上发送,都会 panic.
上面的 DATA RACE 属于幸运,没有 panic。
chan 关闭时的原则是:不要在接收协程中关闭,并且,如果有多个发送者时就不要关闭chan了。
上面的DATA RACE 是在接收协程中关闭chan.
文中详细列出了多种方案关闭chan.
如果粗暴点,可以直接加个 recover. 其他方案都是要保证发送完成后再关闭。
您可能感兴趣的文章:
golang chan 关闭时的原则
Golang channel 使用指南
golang同步机制之通道
android 读写串口中文字符串_golang面试题:对已经关闭的的chan进行读写,会怎么样?为什么?...
Go语言并发模型:以并行处理MD5为例
go语言管道总结
2020-10-19Go语言goroutine和channel
golang的channel机制
Golang并发:并发协程的优雅退出
Go语言 | goroutine不只有基础的用法,还有这些你不知道的操作