我正在一场数据竞赛中,我还不太清楚为什么。使用-race
命令运行测试时,我已将其范围缩小到尝试在读取list.List
时尝试访问它,但Mutexes似乎没有任何作用。
我在数组中有多个* list.list,像这样:
type MyList struct {
mutex sync.Mutex
*list.List
}
type SomeObj struct {
data string
}
var myListOfLists [10]MyList
我正在像这样从列表中读取和书写:
list := myListOfLists[someIndex]
list.mutex.Lock()
for e := list.Front(); e != nil; e = e.Next() {
if (...) {
list.MoveToFront(e)
}
}
list.mutex.Unlock()
在另一个goroutine中,还尝试读取并建立完整列表以返回
var fullCopy []*SomeObj
list := myListOfLists[someIndex]
list.mutex.Lock()
for e := list.Front(); e != nil; e = e.Next() {
fullCopy = append(fullCopy, e.Value.(SomeObj))
}
list.mutex.Unlock()
答案 0 :(得分:1)
语句list := myListOfLists[someIndex]
将数组元素复制到变量list
。这将复制互斥锁,从而阻止互斥锁工作。 go vet
命令报告此问题。
您可以通过使用指向数组元素的指针来避免复制:
list := &myListOfLists[someIndex]
另一种方法是使用指向MyList
的指针数组。在使用它时,最好在MyList
中使用列表值代替列表指针:
type MyList struct {
mutex sync.Mutex
list.List
}
var myListOfLists [10]*MyList
for i := range myListOfLists {
myListOfLists[i] = &MyList{}
}