金庆的专栏

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  423 随笔 :: 0 文章 :: 454 评论 :: 0 Trackbacks
golang chan 关闭时的原则

(金庆的专栏 2020.1)

golang 程序中检测到 DATA RACE, 是 chan 关闭和发送冲突:

==================
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)

查了一下 chan 关闭的正确做法,发现了一篇非常详细的文章:
[How to Gracefully Close Channels](https://go101.org/article/channel-closing.html)

文中指出,chan 多次关闭,或者在关闭的 chan 上发送,都会 panic.
上面的 DATA RACE 属于幸运,没有 panic。

chan 关闭时的原则是:不要在接收协程中关闭,并且,如果有多个发送者时就不要关闭chan了。

上面的DATA RACE 是在接收协程中关闭chan.

文中详细列出了多种方案关闭chan.
如果粗暴点,可以直接加个 recover. 其他方案都是要保证发送完成后再关闭。

posted on 2020-01-08 19:46 金庆 阅读(828) 评论(0)  编辑 收藏 引用 所属分类: 3. Golang

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理