写点什么

今天聊一聊 Golang 的互斥锁吧

用户头像
Regan Yue
关注
发布于: 3 小时前
今天聊一聊Golang的互斥锁吧

今天聊一聊 Golang 的互斥锁吧

今天我们来聊一聊锁吧,我们都知道有并发就有并发安全的问题。对于有的变量不能是并发运行访问的。比如银行的存取款业务,假如可以并发进行的话,你想一想你往银行存这个月的工资 200 万,你老婆同一时间在银行取 200 万去做美容。假如不使用锁,你存完之后发现金额没有变化,你老婆取完钱后发现钱也没有变化。你是慌死了,那你老婆不高兴坏了.......


所以我们这里就需要用到锁,当一个人访问这个业务时,就给它加上锁,别人就不能访问了。


看一看这个存钱的例子:


var wg sync.WaitGroupfunc main() {  var money = 2000  for i:=0;i<10;i++{    wg.Add(1)    go func() {      for j:=0;j<100;j++{        money += 1      }      wg.Done()    }()  }  wg.Wait()  fmt.Println("最终金额",money)}
复制代码


这个例子就是 10 个人每个人给你存 100 块钱。这一百块钱分一百次存。这样存完后我们就有三千块钱了。


我们看一看运行结果:


最终金额 3000
复制代码


好像是没问题哦!那我们加大一下存款金额吧。让 10 个人每个人存 1000,这一千块钱分一千次存,这样我们就会得到一万二千块钱,来看一看运行结果吧!


最终金额 10366
复制代码


是不是和我们预想得不一样?


这就是出现了并发安全问题。


对于这种问题,我们应该不允许并发访问。


然后我们看看怎么使用互斥锁解决这类问题吧!


func main() {  var money = 2000
var mt sync.Mutex
wg.Add(1) go func() { fmt.Println("搏达试图抢断")
mt.Lock() fmt.Println("搏达抢断成功")
money -= 300 <- time.After(10 * time.Second)
mt.Unlock() fmt.Println("搏达扔了球") wg.Done() }()
wg.Add(1) go func() { fmt.Println("搏达试图跳舞")
mt.Lock() fmt.Println("搏达跳舞成功")
money -= 500 <- time.After(10 * time.Second) mt.Unlock() fmt.Println("搏达放弃跳舞") wg.Done() }()
wg.Wait()
}
复制代码


这段程序的意义是两个协程同时抢锁,跳舞协程先抢到锁的话,搏达就开始跳舞,然后跳完舞解锁,抢断协程开始抢到锁,然后搏达结束跳舞开始抢断。如果抢断协程先抢到锁的话,搏达就先开始抢断然后再跳舞。


运行结果是


搏达试图抢断搏达抢断成功搏达试图跳舞搏达扔了球搏达跳舞成功搏达放弃跳舞
复制代码


我们可以看到,搏达扔了球才能开始跳舞。这就是锁的功劳,让搏达不至于一边跳舞一边抢断而累趴。

发布于: 3 小时前阅读数: 2
用户头像

Regan Yue

关注

还未添加个人签名 2020.08.12 加入

对Go、Python、网络安全、区块链感兴趣.

评论

发布
暂无评论
今天聊一聊Golang的互斥锁吧