• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Eysa
博客园    首页    新随笔    联系   管理    订阅  订阅

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

何为竞态?如何解决?

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

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

先上代码:

输出:

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

改一下代码:

输出:

因为加了锁,这1000个协程是按照队列的顺序执行12行,所以稳定输出 final value of x 1000

再看:

输出:

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

 

 

 

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

Mutex vs 信道

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

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

总体说来,当 Go 协程需要与其他协程通信时,可以使用信道。而当只允许一个协程访问临界区时,可以使用 Mutex。

就我们上面解决的问题而言,我更倾向于使用 Mutex,因为该问题并不需要协程间的通信。所以 Mutex 是很自然的选择。

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

 

posted @ 2019-02-21 19:31  Eysa  阅读(376)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3