美文网首页
【Golang】竞态条件 (Race Conditions)

【Golang】竞态条件 (Race Conditions)

作者: liqingbiubiu | 来源:发表于2021-10-13 18:43 被阅读0次
欢迎关注微信公众号:全栈工厂

1. 什么是竞态条件?

竞态条件是指在并发环境中,当有多个事件同时访问同一个临界资源时,由于多个事件的并发执行顺序的不确定,从而导致程序输出结果的不确定,这种情况我们称之为竞态条件 (Race Conditions)或者竞争冒险(race hazard)。
在golang的多协程环境中比较容易出现竞态条件,例如以下代码:

package main

import (
    "sync"
)

var wg sync.WaitGroup
var Total = 0

func main() {
    for concurrence := 0; concurrence < 1000; concurrence++ {
        wg.Add(1)
        go goroutine()
    }
    wg.Wait()
    println("Total:", Total)
}

func goroutine() {
    Total++
    wg.Done()
}

上述代码,我们执行了5次,没吃执行结果都不一样:


其最主要的原因就是由于多协程同时访问临界变量Total,从而出现脏读,导致1000个协程的累加和最终小于1000

2. 怎么发现竞态条件?

在golang 1.1版本中,引入了竞态条件检测工具(race detector),只要带编译执行时加入 -race 参数即可:

go build -race main.go
或:
go run -race main.go

用上述命令执行程序,我们会发现:


执行结果警告第20行出现竟态条件,这样我们就能快速定位问题代码。

3. 如何修复竟态条件?

给临界代码去添加互斥锁可以很好的解决竞态条件问题,例如:

package main

import (
    "sync"
)

var wg  sync.WaitGroup
var Total = 0
var mu sync.Mutex

func main() {
    for concurrence := 0; concurrence < 1000; concurrence++ {
        wg.Add(1)
        go goroutine(&wg)
    }
    wg.Wait()
    println("Total:", Total)
}

func goroutine(wg *sync.WaitGroup) {
    mu.Lock()
    Total++
    mu.Unlock()
    wg.Done()
}

我们对全局变量Total的读写添加了互斥锁,这样我们再执行的时候就不再报竟态条件警告了。

相关文章

  • 【Golang】竞态条件 (Race Conditions)

    欢迎关注微信公众号:全栈工厂 1. 什么是竞态条件? 竞态条件是指在并发环境中,当有多个事件同时访问同一个临界资源...

  • 并发的各种概念定义

    数据竞争(Data Race) 数据共享读, 数据可写(会发生变化) 竞态条件(Race Condition) 多...

  • 并发编程-基础知识

    什么是线程安全 无状态对象一定是线程安全的 原子性 竞态条件(Race Condition):不恰当的执行时序导致...

  • 第二部分 进程管理 同步与死锁

    第六章 同步 竞态,竞争条件,(race condition) 是指多个进程(线程)并发访问和操作同一数据并且执行...

  • 【链安】竞态条件漏洞分析及详细修复建议

    什么是竞态条件 【竞态条件】竞态条件的官方定义是如果程序的执行顺序改变会影响结果,它就属于一个竞态条件。在智能合约...

  • 什么是竞态条件?

    如果程序运行顺序的改变会影响最终结果,这就是一个竞态条件(race condition)。 例如:两个线程执行下面...

  • 数据库事务--事务隔离级别

    数据库里关于事务的并发问题,也叫做竞态条件(race condition)。它是描述并发事务中,一个事务需要读取另...

  • go 竞态检测

    Go 工具套件在 Go 版本 1.1 引入了一个竞态检测工具(race detector)。这个竞态检测工具是在编...

  • 【读书札记】golang并发编程

    来自图书《Concurrency In Go》 1,Race Conditions 竞争关系 这样的代码就有3种可...

  • 竞态条件和临界区

    当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。导致竞态条件发生的代码区称作临界区。

网友评论

      本文标题:【Golang】竞态条件 (Race Conditions)

      本文链接:https://www.haomeiwen.com/subject/tadeoltx.html