首页 > C/C++ > geth以太坊源码分析-P2P服务发现 UDP协议存在死循环没有优雅退出

geth以太坊源码分析-P2P服务发现 UDP协议存在死循环没有优雅退出

2018年6月23日 发表评论 阅读评论 28514次阅读    

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


不过就算不处理,也不会带来什么影响,代码不优雅而已。

Share
分类: C/C++ 标签: ,

注意: 评论者允许使用'@user空格'的方式将自己的评论通知另外评论者。例如, ABC是本文的评论者之一,则使用'@ABC '(不包括单引号)将会自动将您的评论发送给ABC。使用'@all ',将会将评论发送给之前所有其它评论者。请务必注意user必须和评论者名相匹配(大小写一致)。