首页 > 解决方案 > 使用 -race 标志时,GO 中的竞态条件是什么意思

问题描述

考虑以下代码:

package main

import (
    "fmt"
    "sync"
)

func main() {
var a int
m := new(sync.Mutex)

wg := sync.WaitGroup{}
wg.Add(2)

go func(){
    m.Lock()
    a = 2
    m.Unlock()
    wg.Done()
}()

go func(){
    //m.Lock()
    a = 9
    //m.Unlock()
    wg.Done()
}()

wg.Wait()

fmt.Println(a)
}

如果我们使用 -race 标志运行此代码,我们会收到存在竞争条件的警告。

1)这种竞争条件可能会出现什么问题?

如果我们在第二个例程中取消注释锁定,我们不会收到竞争条件警告。但是我们可以有不同的输出,所以存在竞争条件。

2)为什么现在我们没有竞争条件警告?

标签: goconcurrencyrace-condition

解决方案


1)这种竞争条件可能会出现什么问题?

  • 未定义的行为
  • 内存损坏
  • 崩溃从字面上看,最糟糕的结果是不知道变量中的值并可能具有完全无效的值:p

2)为什么现在我们没有竞争条件警告?

Mutex 是一种可以保证原子性的原语。当锁被取消注释时,运行时/操作系统完全同步对锁保护的语句的访问。iea永远不会同时设置为 2 和 9。

这里可能会影响性能(您的应用程序可能永远不会遇到它们),因为这些是序列化操作。这通常是一个很好的权衡,因为它以潜在的性能影响为代价确保了正确性。


go 文档围绕这个问题的细节提供了惊人的资源:


推荐阅读