go语言的潜在竞争条件

时间:2017-04-15 00:38:39

标签: go

我不确定为什么以下代码有竞争条件,有人可以给我一个提示吗?我认为没有潜在的竞争条件。先感谢您。

type PossiblySafeCounter struct {
    mu sync.Mutex
    sum int
}

func (c *PossiblySafeCounter) inc() {
   c.mu.Lock();
   defer c.mu.Unlock();
   go func() {
       c.sum++
   }() 
}
func (c *PossiblySafeCounter) read() int {
    c.mu.Lock();
    defer c.mu.Unlock();
    return c.sum
 }

1 个答案:

答案 0 :(得分:6)

c.sum++位于goroutine中,与执行inc()方法无关。当inc()方法退出defer时,互斥锁的解锁将会发生并很可能在错误的时间发生,从而导致竞争状态。

正如@Flimzy建议使用atomic.AddInt32一样,根本不需要互斥锁。

两个基于互斥的解决方案要么不在goroutine中增加:

func (c *PossiblySafeCounter) inc() {
   c.mu.Lock();
   defer c.mu.Unlock();
   c.sum++
}

或在 goroutine中锁定和解锁

func (c *PossiblySafeCounter) inc() {
   go func() {
       c.mu.Lock();
       defer c.mu.Unlock();
       c.sum++
   }() 
}

但老实说,在这个例子中,做任何类型的goroutine都没有意义。为什么你需要将增量放在goroutine中?