【发布时间】:2018-04-26 10:01:00
【问题描述】:
我有一些 Golang 代码,非常间歇性地(每隔几个小时一次)导致恐慌,我需要一些指导来了解如何找到原因。代码是这样的(带行号):
audio-process.go:
var MyChannel chan<- interface{}
var newDatagramList = list.New()
func operateAudioProcessing() {
var channel = make(chan interface{})
MyChannel = channel
newDatagramList.Init()
...
415 go func() {
416 for cmd := range channel {
417 switch msg := cmd.(type) {
418 case *MyThing:
419 {
420 newDatagramList.PushBack(msg)
421 }
422 }
423 }
424 }()
425 }
...当在第 420 行调用 newDatagramList.PushBack() 时发生恐慌。发送到此通道的代码是:
audio-in.go:
thing := new(MyThing)
...
MyChannel <- thing
...并且,为了完成图片,有一个单独的定时go func() 处理newDatagramList,如下所示:
go func() {
var next *list.Element
for _ = range processTicker.C {
for newElement := newDatagramList.Front(); newElement != nil; newElement = next {
next = newElement.Next();
myProcessingFunction(newElement.Value.(*MyThing))
newDatagramList.Remove(newElement)
}
}
恐慌输出是:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x5702d1]
goroutine 12 [running]:
panic(0x76e520, 0xc82000e100)
/usr/lib/go-1.6/src/runtime/panic.go:481 +0x3e6
container/list.(*List).PushBack(0xc820054e40, 0x6c4f80, 0xc827294e20, 0xc8273e0b01)
/usr/lib/go-1.6/src/container/list/list.go:139 +0x1c1
main.operateAudioProcessing.func2(0xc8200164e0, 0xc82000f310, 0xc820024078, 0x240)
/home/rob/gocode/src/audio-process.go:420 +0x58b
created by main.operateAudioProcessing
/home/rob/gocode/src/audio-process.go:442 +0x5ba
恐慌告诉我这里有什么问题?首先没有关于分配和发送到频道的投诉,所以我不明白这怎么可能是错误的。 newDatagramList 显然已初始化(并且通道已经运行并接收消息一段时间了)。
我如何确定是什么让我爆炸了?
【问题讨论】:
-
我认为恐慌是说问题出在 list 包中的 Pushback 方法中。有点怀疑 newDatagramList 是一个全局包。可能是竞争条件,因为列表不是线程安全的 - newDatagramList 是从另一个 goroutine 访问的吗?
-
您可以使用
go run -race测试您的应用,看看您是否有数据竞争。 -
golang.org/src/container/list/list.go?s=3579:3626#L128 在 `container/list List 上看起来根本没有任何同步
-
我想知道
go func()循环是否可能会尝试处理和删除添加了一半的项目? -
我很确定根本原因是
container/list访问不是线程安全的,Remove()和PushBack/Front/Next由于访问不同步而创建了竞争条件 @987654322 @github.com/golang/go/blob/release-branch.go1.6/src/container/…
标签: go