list.List 并发访问与互斥量的数据竞争
Data race with list.List concurrent access with mutexes
我正在进行数据竞赛,我不太明白为什么。 运行 我使用 -race
命令进行的测试 我已将范围缩小到尝试在读取 list.List
时访问它,但我的互斥体似乎没有做任何事情。
我在一个数组中有许多 *list.Lists,如下所示:
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 中也试图读取并构建完整列表 return
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()
语句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{}
}
我正在进行数据竞赛,我不太明白为什么。 运行 我使用 -race
命令进行的测试 我已将范围缩小到尝试在读取 list.List
时访问它,但我的互斥体似乎没有做任何事情。
我在一个数组中有许多 *list.Lists,如下所示:
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 中也试图读取并构建完整列表 return
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()
语句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{}
}