go - Go 语言中的潜在竞争条件

标签 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
 }

最佳答案

c.sum++ 位于一个独立于 inc() 方法执行的 goroutine 中。当 inc() 方法退出时,互斥锁的延迟解锁将会发生并且很可能发生在错误的时间,从而导致竞争条件。

正如@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 中?

关于go - Go 语言中的潜在竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43420958/

相关文章:

go - 使用Go处理后期请求中的多个文件

go - 如何使用特定时区解析时间

go - 传入请求:具有自定义类型字段的上下文

go - 带有 nil 的指针函数接收器是否安全?

c - 目前有哪些方法可以让您在 C 中调用 Go 函数?

orm - Gorm Golang 获取集合及其关系

go - 在实现相同接口(interface)的多个结构上定义方法

go - 将Go app部署到Google App Engine时出现问题

multithreading - 工作池模式 - 死锁

Golang fsnotify 在 Windows 上为同一个文件发送多个事件