Go语言goroutine中time.Sleep未产生预期阻塞效果问题咨询
问题成因
- 核心原因是全局变量
timeToSleep被main函数内的局部变量屏蔽,三个goroutine读取的sleep时长始终为0
你在代码全局声明了var timeToSleep time.Duration,但在main函数中解析输入的sleep参数时,使用了短变量声明语法:=:
该语法会在main函数的当前作用域创建一个全新的局部变量timeToSleep, err := time.ParseDuration(sleepSeconds)timeToSleep,你解析得到的5s时长仅赋值给了这个局部变量,全局的timeToSleep始终保持类型零值0s。而one、two、three三个goroutine中引用的是全局的timeToSleep,因此time.Sleep(timeToSleep)等价于time.Sleep(0),完全没有阻塞效果。 - 无缓冲通道的特性进一步放大了这个异常表现
你创建的myChan是无缓冲通道,发送操作会阻塞直到有接收方取走数据。由于goroutine消费时没有sleep阻塞,消费速度极快,main函数的for循环可以无停顿地持续生产数据,程序会一直运行直到你手动发送中断信号(Ctrl+C)停止,你观察到的2.316s就是你从启动程序到按下停止的实际时长。
修复方案
把main函数中解析duration的代码修改为给全局变量赋值即可,替换为如下代码:
var err error timeToSleep, err = time.ParseDuration(sleepSeconds)
去掉短变量声明的:,就不会创建新的局部变量,解析得到的时长会正确赋值给全局的timeToSleep,三个goroutine的sleep逻辑就会正常生效。
内容的提问来源于stack exchange,提问作者Alwin Doss
相关产品推荐
相关产品推荐

