即使在golang中使用sync.Mutex也会出现竞争情况
发布时间:2020-12-16 09:27:31 所属栏目:大数据 来源:网络整理
导读:完整代码在这里: https://play.golang.org/p/ggUoxtcv5m go run -race main.go说那里有竞争条件我无法解释. 不过,该程序输出了正确的最终结果. 精华: type SafeCounter struct { c int sync.Mutex}func (c *SafeCounter) Add() { c.Lock() c.c++ c.Unlock(
完整代码在这里:
https://play.golang.org/p/ggUoxtcv5m
go run -race main.go说那里有竞争条件我无法解释. 不过,该程序输出了正确的最终结果. 精华: type SafeCounter struct { c int sync.Mutex } func (c *SafeCounter) Add() { c.Lock() c.c++ c.Unlock() } var counter *SafeCounter = &SafeCounter{} // global 在增量器中使用* SafeCounter: func incrementor(s string) { for i := 0; i < 20; i++ { x := counter x.Add() counter = x } } incrementor方法在main中生成两次: func main() { go incrementor() go incrementor() // some other non-really-related stuff like // using waitGroup is ommited here for problem showcase } 因此,正如我所说,去运行-race main.go将始终说有一个比赛cond发现. 此外,最终的结果总是正确的(至少我已经运行了多次这个程序,它总是说最终计数器是40,这是正确的). Incrementor1: 0 Counter: 2 Incrementor2: 0 Counter: 3 Incrementor2: 1 Counter: 4 // ang the rest is ok 所以,那里缺少打印1. 有人可以解释为什么有竞争条件我的代码? 解决方法
你有很多种族条件,所有比赛都由比赛探测器指出:
x := counter // this reads the counter value without a lock fmt.Println(&x.c) x.Add() counter = x // this writes the counter value without a lock time.Sleep(time.Duration(rand.Intn(3)) * time.Millisecond) fmt.Println(s,i,"Counter:",x.c) // this reads the c field without a lock > race#1在增量器中读取和写入计数器值之间> race#2是在incrementor中对计数器值的并发写入之间> race#3介于fmt.Println中x.c字段的读取和Add方法中x.c的增量之间. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |