为什么会有the channel used with signal.Notify should be buffered?

最近写代码 gofmt报错了,引起报错的语句如下:

	c := make(chan os.Signal)
	signal.Notify(c, syscall.SIGTERM)
	<-c

用gofmt检查代码的时候发现报错:
the channel used with signal.Notify should be buffered

于是点开看了一下signal.Notify函数里面到底是咋回事
先看到的是注释已经写清楚了,让channel用有buffer的通道:
在这里插入图片描述
如果不用有buffer的通道会咋样呢?
先说一下结论:
如果使用无buffer通道,可能会造成信号丢失。

换句话说,如果信号的发送者只发送一次信号的话,第三行代码可能会因为信号丢失而永远阻塞:

	c := make(chan os.Signal)
	signal.Notify(c, syscall.SIGTERM)
	<-c

当然我就蒙b了,我都没有从通道读数据呢?数据怎么可能就没了?

看了一下signal.Notify的源代码 主要看下面这一点就够了
在这里插入图片描述
最终信号会被传入process这个函数里,然后执行截图中的select语句。
select 语句配合channel的效果就是,随机执行非阻塞的case,这里由于可能没有人读c这个chan,因此case c<-sig就是阻塞的,所以这个case是不执行的 直接执行default,然后执行下一个循环了,所以sig就被丢掉了。
所以 当信号的发起者发送的进程所建立的chan是一个无buffer chan,很有可能这个信号就丢掉了。丢掉的地方不是在传入chan后丢掉的,而是这个signal直接就没有往c里面传,就扔掉了,当然会出现信号丢失的问题。

这里还有一个疑问需要有空的时候想一下:既然存在这样的问题,go为什么要这样设计呢???

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值