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
不过就算不处理,也不会带来什么影响,代码不优雅而已。

近期评论