• EasyNVR程序崩溃并报“Add called concurrently with Wait”


    EasyNVR是TSINGSEE青犀视频比较热门的产品之一,很多用于室内固定IP摄像头监控的场景都能够使用。有的开发者在使用之前可能会担心系统是否稳定?掉线是否频繁?是否支持设备重连?想了解一下的朋友们可以到我们官网 easynvr.com 阅览,也可以自主进行下载试用。EasyNVR已经是一个非常成熟的视频平台了,系统稳定,且支持二次开发,是很多视频行业监控直播的不二之选。

    在一个EasyNVR现场,出现程序崩溃的问题 Add called concurrently with Wait,对应日志如下:

    根据崩溃日志查看,明显能够看出是 waitGroup 结构体已经处于 Wait() 状态,但是又调用了一次 waitGroup.Add() 方法导致程序崩溃。原始代码如下:

    wg := sync.WaitGroup{}

    for i := 0; i < runNumber; i++ {

    go func(offlineChannel *channels.ChannelInfo) {

    defer func() {

    if p := recover(); p != nil {

    log.Error("OfflineConnecting Connecting panic, %v", p)

    log.Error("OfflineConnecting Connecting debug stack : %v", string(debug.Stack()))

    }

    wg.Done()

    }()

    wg.Add(1)

    // 开始尝试连接设备 Connecting,连接完毕后,会异步上线

    offlineChannel.Connecting()

    }(offlineChannels[alreadyRunNumber])

    alreadyRunNumber = alreadyRunNumber + 1

    }

    wg.Wait()

    由程序看出,代码是在 go 协程中调用了 wg.Add(1) 方法,因此有可能在 wg.Wait() 正在运行的时候出现 go 协程中加一的操作,因此崩溃。

    将 wg.Add() 不再协程中加一,代码如下:

    wg := sync.WaitGroup{}

    for i := 0; i < runNumber; i++ {

    wg.Add(1)

    go func(offlineChannel *channels.ChannelInfo) {

    defer func() {

    if p := recover(); p != nil {

    log.Error("OfflineConnecting Connecting panic, %v", p)

    log.Error("OfflineConnecting Connecting debug stack : %v", string(debug.Stack()))

    }

    wg.Done()

    }()

    // 开始尝试连接设备 Connecting,连接完毕后,会异步上线

    offlineChannel.Connecting()

    }(offlineChannels[alreadyRunNumber])

    alreadyRunNumber = alreadyRunNumber + 1

    }

    wg.Wait()

    wg.Add(1) 放在 go 程序外侧。修改后,代码即可成功运行。

  • 相关阅读:
    《Effective C++》第8章 定制new和delete-读书笔记
    《TCP/IP详解卷1:协议》第3章 IP:网际协议(2)-读书笔记
    【剑指Offer】14合并两个排序的链表
    【剑指Offer】13反转链表
    【剑指Offer】12链表中倒数第k个结点
    【剑指Offer】11调整数组顺序使奇数位于偶数前面
    【剑指Offer】10数值的整数次方
    【剑指Offer】09二进制中1的个数
    【剑指Offer】08矩形覆盖
    【剑指Offer】07变态跳台阶
  • 原文地址:https://www.cnblogs.com/EasyNVR/p/15724503.html
Copyright © 2020-2023  润新知