type Stat struct { counters map[string]*int64 countersLock sync.RWMutex averages map[string]*int64 averagesLock sync.RWMutex }
它在下面被称为
func (s *Stat) Count(name string) { s.countersLock.RLock() counter := s.counters[name] s.countersLock.RUnlock() if counter != nil { atomic.AddInt64(counter, int64(1)) return } }
我的理解是,我们首先锁定接收器s(这是Stat类型),然后如果计数器确实存在,则将其添加。
问题:
Q1:为什么我们需要锁定它?RWMutex甚至是什么意思?
RWMutex
问题2:s.countersLock.RLock()-这是否会锁定整个接收器或仅锁定Stat类型的counters字段?
s.countersLock.RLock()
问题3:s.countersLock.RLock()-这是否会锁定平均值字段?
问题4:为什么要使用RWMutex?我以为通道是处理Golang中并发的首选方法?
问题5:这是什么atomic.AddInt64。为什么在这种情况下我们需要原子的?
atomic.AddInt64
问题6:为什么要在添加之前立即解锁?
问题: Q1:为什么我们需要锁定它?RWMutex甚至是什么意思?
RW代表读/写。CF文档:http : //golang.org/pkg/sync/#RWMutex。
我们需要锁定它,以防止其他例程/线程在处理它时更改该值。
作为互斥锁,只有在调用RLock()函数时才会发生锁定。如果任何其他goroutine已调用WLock(),则它将阻塞。您可以RLock()在同一goroutine中调用任意数量的代码,它不会锁定。
RLock()
WLock()
因此它不会锁定任何其他字段,甚至也不会s.counters。在您的示例中,您锁定了地图查找以找到正确的计数器。
s.counters
不,正如第二季度所说,RLock只有他自己可以锁。
RLock
频道非常有用,但有时不够用,有时没有意义。
在这里,当您锁定地图访问权限时,互斥锁才有意义。使用chan时,您必须具有1的缓冲chan,然后才发送和接收。不是很直观。
此函数将以原子方式递增给定变量。在您的情况下,您有一个竞态条件:counter是一个指针,并且在释放锁之后和调用之前可以销毁实际变量atomic.AddInt64。如果您不熟悉这种事情,我建议您坚持使用互斥锁,并在锁定/解锁之间进行所有需要的处理。
counter
你不应该。
我不知道您要做什么,但这是一个(简单的)示例:https : //play.golang.org/p/cVFPB-05dw