geth以太坊源码分析-P2P服务发现 UDP协议存在死循环没有优雅退出
geth代码时, 到p2p/discover/udp.go readLoop()函数的处理的时候,直接一个死循环没有监听closing管道,所以基本上是不能优雅退出的。
可能是作者觉得这个不重要,所以没管它?
看下如下代码,测试了一下,无法优雅退出,基本上只能靠主进程主动退了。
func (t *udp) readLoop(unhandled chan<- ReadPacket) { defer t.conn.Close() if unhandled != nil { defer close(unhandled) } // Discovery packets are defined to be no larger than 1280 bytes. // Packets larger than this size will be cut at the end and treated // as invalid because their hash won't match. buf := make([]byte, 1280) for {//下面是不是死循环了?退出的时候怎么处理的?有没有监听closeing //测试了一下,死循环了。。。退出不了的,因为没有监听退出事件 nbytes, from, err := t.conn.ReadFromUDP(buf) if netutil.IsTemporaryError(err) { // Ignore temporary read errors. log.Debug("Temporary UDP read error", "err", err) continue } else if err != nil { // Shut down the loop for permament errors. log.Debug("UDP read error", "err", err) return } if t.handlePacket(from, buf[:nbytes]) != nil && unhandled != nil { select { case unhandled <- ReadPacket{buf[:nbytes], from}: default: } } } }
相反,在loop函数里面,就监听了程序关闭事件。
func (t *udp) loop() { for { resetTimeout() select { case <-t.closing: for el := plist.Front(); el != nil; el = el.Next() { el.Value.(*pending).errc <- errClosed } return
不过就算不处理,也不会带来什么影响,代码不优雅而已。
近期评论