有人遇到过 Golang select case 语句和 default 语句都没执行的情况吗?

2021-08-10 11:10:52 +08:00
 Morriaty

程序大致逻辑如下,会正常运行一段时间,receiving msgsleeping会交替打印,但运行一段时间后最后输出一段pipeline sleeping之后就再也没有日志了,没有pipeline terminate,没有 panic,也没有到 defer 那一步

var sigChan = make(chan os.Signal, 1)

func init() {
	signal.Notify(
		sigChan,
		os.Kill,
		os.Interrupt,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT,
	)
}

func (ip *InnerPipeline) Run() {

	defer func() {
		log.Infof("pipeline<%s> defer exit", ip.name)
	}()

	for {

		select {
		case im := <-ip.messageQueue:
			log.Debugf("receiving msg %+v", im)

			// some logic ....
                        xxxxxxxxxxxxxxx

			log.Debugf("quit case")

		case <-sigChan:
			log.Infof("pipeline terminate")
			return

		default:
			log.Debugf("current chan len: %d", len(ip.messageQueue))
			
			// some logic ....
                        xxxxxxxxxxxxxxx            

			log.Debugf("pipeline<%s> sleeping...", ip.name)
			time.Sleep(50 * time.Millisecond)
		}
	}
}
2351 次点击
所在节点    程序员
13 条回复
index90
2021-08-10 11:41:59 +08:00
大概率你的 main 函数还没等 Run 函数 return 就结束了
paulter
2021-08-10 11:50:42 +08:00
提问之前,起码先抽出一个最小可运行的 demo 程序,以便重现问题。
Morriaty
2021-08-10 11:53:50 +08:00
@index90 忘了描述了,主程序没有结束,msg produce 的地方依然在打印日志
Hstar
2021-08-10 11:55:44 +08:00
建议排查 default 块里的代码, 精简到只有 log 和 Sleep 试试是否在循环
gamexg
2021-08-10 12:02:43 +08:00
golang pprof 直接看卡在哪一步了
fds
2021-08-10 13:00:54 +08:00
for 开始时打印下 ip.messageQueue
nuk
2021-08-10 13:34:22 +08:00
gdb 一把就知道了啊。。
Morriaty
2021-08-10 14:25:22 +08:00
@Hstar @fds 好的我试试
@gamexg 我加下看看,但感觉不一定看得懂🤣
@nuk 开发环境无法复现,生产环境要跑一两个小时才会出现这个问题,这种情况下怎么打断点啊?
nuk
2021-08-10 16:27:57 +08:00
@Morriaty 隔一会检查一下 log,要是太久没出现 log 就 dump stack 出来。。不过你这个问题我觉得像是 signal channel 过早关闭。。于是就在里面死循环了。。
cyrivlclth
2021-08-10 17:31:05 +08:00
可能是 some logic 里面的逻辑耗时太长卡住了吧。
Morriaty
2021-08-10 17:32:42 +08:00
@nuk 额,代码里是没有主动关闭 chan 的地方,而且就算关闭了,也会打出 pipeline terminate 日志吧
Morriaty
2021-08-10 17:33:25 +08:00
@cyrivlclth 如果是 some logic 堵住了,就不会打印 sleeping 的日志啊,实际日志是停在 sleeping 这里的
nacosboy
2021-08-10 18:53:48 +08:00
@Morriaty 我觉得也是 some logic 在特定场景下 block 住了,打印出的 sleeping 日志,可能是上一次循环打印出的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/794809

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX