程序大致逻辑如下,会正常运行一段时间,receiving msg
和sleeping
会交替打印,但运行一段时间后最后输出一段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) } } }
![]() | 1 index90 2021-08-10 11:41:59 +08:00 大概率你的 main 函数还没等 Run 函数 return 就结束了 |
2 paulter 2021-08-10 11:50:42 +08:00 提问之前,起码先抽出一个最小可运行的 demo 程序,以便重现问题。 |
4 Hstar 2021-08-10 11:55:44 +08:00 建议排查 default 块里的代码, 精简到只有 log 和 Sleep 试试是否在循环 |
![]() | 5 gamexg 2021-08-10 12:02:43 +08:00 golang pprof 直接看卡在哪一步了 |
6 fds 2021-08-10 13:00:54 +08:00 for 开始时打印下 ip.messageQueue |
![]() | 7 nuk 2021-08-10 13:34:22 +08:00 gdb 一把就知道了啊。。 |
![]() | 8 Morriaty OP |
![]() | 9 nuk 2021-08-10 16:27:57 +08:00 @Morriaty 隔一会检查一下 log,要是太久没出现 log 就 dump stack 出来。。不过你这个问题我觉得像是 signal channel 过早关闭。。于是就在里面死循环了。。 |
![]() | 10 cyrivlclth 2021-08-10 17:31:05 +08:00 可能是 some logic 里面的逻辑耗时太长卡住了吧。 |
![]() | 11 Morriaty OP @nuk 额,代码里是没有主动关闭 chan 的地方,而且就算关闭了,也会打出 pipeline terminate 日志吧 |
![]() | 12 Morriaty OP @cyrivlclth 如果是 some logic 堵住了,就不会打印 sleeping 的日志啊,实际日志是停在 sleeping 这里的 |