golang chan 关闭时的原则

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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值