前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >协程锁

协程锁

作者头像
酷走天涯
发布2019-06-11 16:31:28
5380
发布2019-06-11 16:31:28
举报
  • 什么是竞争
  • Mutex 的使用
什么是竞争

看下面的代码

代码语言:javascript
复制
package main

import (
    "sync"
    "fmt"
)

var total = 0

func add(num int,ws * sync.WaitGroup){
   total += 1
   ws.Done()
}

func main() {
  var ws sync.WaitGroup
  ws.Add(1000)
  for i:=0;i<1000;i++{
      go add(1,&ws)
  }
  ws.Wait()
  fmt.Println(total)
}

我们对一个变量total 进行1000次 +1 操作,不过我们是在多个协程中进行的,猜猜结果如何,我们运行五次看结果

image.png

image.png

image.png

image.png

image.png

竞争发生的概率,和你的协程数量成正比,如果你的协程数很少的话,可能运行几百次发现不了这个现象

那如何避免这个问题呢?


Mutex

Mutex 用于提供一种加锁机制(Locking Mechanism),可确保在某时刻只有一个协程在临界区运行,以防止出现竞态条件。

直接看代码

代码语言:javascript
复制
package main

import (
    "sync"
    "fmt"
)

var total = 0

func add(num int,ws * sync.WaitGroup,mutex *sync.Mutex){
    mutex.Lock()
   total += 1
   mutex.Unlock()
   ws.Done()
}

func main() {
  var ws sync.WaitGroup
    mutex := sync.Mutex{}
    ws.Add(1000)
  for i:=0;i<1000;i++{
      go add(1,&ws,&mutex)
  }
  ws.Wait()
  fmt.Println(total)
}

运行结果如下

image.png

sync.Mutex 是一个结构体 在操作元素的时候 mutex.Lock() 加锁 执行完毕后 mutex.Unlock()解锁


使用信道处理竞争
代码语言:javascript
复制
package main  
import (  
    "fmt"
    "sync"
    )
var x  = 0  
func increment(wg *sync.WaitGroup, ch chan bool) {  
    ch <- true
    x = x + 1
    <- ch
    wg.Done()   
}
func main() {  
    var w sync.WaitGroup
    ch := make(chan bool, 1)
    for i := 0; i < 1000; i++ {
        w.Add(1)        
        go increment(&w, ch)
    }
    w.Wait()
    fmt.Println("final value of x", x)
}

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

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

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

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

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.12.24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是竞争
  • Mutex
    • 使用信道处理竞争
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档