锁追加切片,没有读锁,所以我可以得到新的长度,但没有元素?



当我为一些实际代码编写golang并行基准测试时,我得到了1个错误。

例如,变量f在函数1中将是nil,为什么?

type foo struct {
name string
}
var s []*foo

race function:

for {
// no lock
length := len(s) // typo, it should be len(s) - 1
f := s[length]
fmt.Println(f.name)
}

race function:

for {
// lock
mu.Lock()
s = append(s, &foo{})
mu.Unlock()
}

互斥锁不影响锁和锁之间的调用(它们不成为原子,这对所有操作都是不可能的),互斥锁是防止数据竞争的,但是你必须在读和写时使用它,你必须在两边使用相同的互斥锁实例。所以这段代码是安全的:

type SyncSlice struct {
inner []int
m     sync.Mutex
}
func (s *SyncSlice) Append(elem int) {
s.m.Lock()
s.inner = append(s.inner, elem)
s.m.Unlock()
}
func (s *SyncSlice) Len() int {
s.m.Lock()
defer s.m.Unlock() // as we have to unlock after returning
return len(s.inner)
}
func (s *SyncSlice) Get(i int) int {
s.m.Lock()
defer s.m.Unlock() // as we have to unlock after returning
return s.inner[i]
}
func (s *SyncSlice) Set(i, value int) {
s.m.Lock()
s.inner[i] = value
s.m.Unlock()
}

虽然只有在直接使用方法而不是字段时才安全。您还必须使用相同的slice实例,因此脚本必须访问SyncSlice

的指针。

相关内容