go语言的潜在竞争条件

vko*_*syj 0 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
 }
Run Code Online (Sandbox Code Playgroud)

Joh*_*don 6

c.sum++是在被独立地调度的执行的够程inc()方法.当inc()方法退出defer时,互斥锁的解锁将发生并且很可能在错误的时间发生,从而导致竞争条件.

正如@Flimzy建议使用atomic.AddInt32将完全取消对互斥量的需求.

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

func (c *PossiblySafeCounter) inc() {
   c.mu.Lock();
   defer c.mu.Unlock();
   c.sum++
}
Run Code Online (Sandbox Code Playgroud)

或者 goroutine中进行锁定和解锁:

func (c *PossiblySafeCounter) inc() {
   go func() {
       c.mu.Lock();
       defer c.mu.Unlock();
       c.sum++
   }() 
}
Run Code Online (Sandbox Code Playgroud)

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

  • 事实上`c.sum ++`正在goroutine中发生意味着互斥锁没有保护任何与增量有关的东西. (2认同)
  • 更好的解决方案是使用[`atomic.AddInt32`](https://golang.org/pkg/sync/atomic/#AddInt32),因此不需要锁定. (2认同)