Go 初体验 - 并发与锁.3 - 竞态

竞态,就是多个协程同时访问临界区,由并发而产生的数据不一样步的状态。并发

这个说的有点low,没办法,我就是这么表达的,官方的请度娘。工具

先上代码:3d

输出:协程

为什么不是1000?就是由于竞态,发生竞态后,最终的输出是以最后一个协程执行的结果为准,但最后一个协程有必定的随机性,不是先跑先完。blog

改一下代码:队列

输出:同步

由于加了锁,这1000个协程是按照队列的顺序执行12行,因此稳定输出 final value of x 1000引用

再看:im

输出:d3

照样稳定输出 final value of x 1000,由于信道的读和写都具备排他性,虽然不是锁住临界区,可是能起到让后来的协程排队的效果。

 

 

 

那么这两种状况怎么选择呢? 引用一个大牛的话:

Mutex vs 信道

经过使用 Mutex 和信道,咱们已经解决了竞态条件的问题。那么咱们该选择使用哪个?答案取决于你想要解决的问题。若是你想要解决的问题更适用于 Mutex,那么就用 Mutex。若是须要使用 Mutex,无须犹豫。而若是该问题更适用于信道,那就使用信道。:)

因为信道是 Go 语言很酷的特性,大多数 Go 新手处理每一个并发问题时,使用的都是信道。这是不对的。Go 给了你选择 Mutex 和信道的余地,选择其中之一均可以是正确的。

整体说来,当 Go 协程须要与其余协程通讯时,可使用信道。而当只容许一个协程访问临界区时,可使用 Mutex。

就咱们上面解决的问题而言,我更倾向于使用 Mutex,由于该问题并不须要协程间的通讯。因此 Mutex 是很天然的选择。

个人建议是去选择针对问题的工具,而别让问题去将就工具。:)

相关文章
相关标签/搜索