我有一些与sync.Mutex
一起使用的Go struct
相关的问题。例如,如果我要使用这个struct
:
type something struct {
aMux sync.Mutex
a map[string]interface{}
bMux sync.Mutex
b int
}
... 在无竞争条件的情况下锁定bMux
和访问b
并同时锁定aMux
和访问a
是否安全?
了解我正在访问结构的指针并使用类似方法同时锁定/解锁互斥锁可能也很有帮助:
func (s *something) addA(k string, v interface{}) {
(*s).aMux.Lock()
(*s).a[k] = v
(*s).aMux.Unlock()
}
func (s *something) addB(k string, v interface{}) {
(*s).bMux.Lock()
(*s).b++
(*s).bMux.Unlock()
}
我的假设是,从理论上讲这应该是安全的,因为您已经可以在结构中锁定互斥锁而不必访问它锁定的字段。 但是当像上面那样取消引用struct
时,Go会复制struct
中的所有值(使其不安全)还是仅修改/检索您指定的字段?
我非常想将互斥锁保持在相同的结构中,因为在我的代码中,我在同一个结构中使用互斥锁分别锁定了多个(最多六个)相关字段。 如果在同一结构中(对于相关字段)具有多个互斥对象是安全的,但是不建议这样做或不建议这样做,为什么?哪种结构更好?
答案 0 :(得分:2)
在单个结构中具有多个互斥对象应该是安全的。请注意不要通过值传递结构,因为互斥体不是引用类型,并且复制它们是错误的(有关更多详细信息,请参见this discussion)。
您不需要显式取消引用,Go会为您完成:
Cookie
应该也能正常工作(在Go tour中)。
我会说这不是很平常的设计。如果可能,我希望互斥锁锁定整个结构。一旦执行了非常精细的锁定,就必须非常小心,我将首先探讨其他选项。
答案 1 :(得分:1)
map
或int
的任何操作都可以共享相同的内容单个互斥锁从golang mutex docs:
不应复制包含此包中定义的类型(即sync.Mutux)的值。