• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

go并发编程之五(sync之互斥锁Mutex)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

Mutex互斥锁相关的介绍使用

1. 互斥锁的定义

互斥锁:是一种同步机制,用于在存在许多执行线程的环境中强制限制对资源的访问。锁旨在实施互斥 并发控制策略。

我们来看一个示意图:

没有锁的时候,A、B、C同时争抢资源E,像打架似的谁也不让谁,有锁了以后,只有A拥有该资源,B/C只能在外面等待
索被释放

2. 互斥锁的使用

想象我们有1w个商品券发给同时发给1w个人,每个人都会得到一张商品券,每张商品券核销码都不一样,且只能核销一次
看如下简化代码:

package main

import (
	"fmt"
	"sync"
)

type GoodsNum struct {
	value int
	lock sync.Mutex // 0
}

func decrGoodNum(clientId int , good *GoodsNum,group *sync.WaitGroup) {
	good.lock.Lock() // 1
	defer func() {
		good.lock.Unlock() //2
		group.Done()
	}()
	good.value--
	fmt.Println("client ",clientId," get the good and good num left ",good.value)
}

func main() {

	var waitGroup sync.WaitGroup
	l := sync.Mutex{} //3
	good := GoodsNum{
		value:10000,
		lock:l, //4
	}
	start := time.Now().UnixNano()
	waitGroup.Add(10000)
	for i := 1 ; i<= 10000 ; i++ {
		go decrGoodNum(i,&good,&waitGroup)
	}
	waitGroup.Wait()
    end := time.Now().UnixNano()
	fmt.Println("exec complete good num left ",good.value)
	fmt.Println("cast time ",end - start,"ns")
}

不加锁的情况下,我们注释掉 0/1/2/3/4 这五处代码,然后执行,结果截图如下:

然后我们打开这五处注释,执行,结果截图如下

然后我们发现,我们没有加锁时,居然多出来 12 张没有发完,这就是之前提到的原子性操作,多个线程同时拿到同一个资源时,同时操作会导致结果的不确定性,然后我们加了互斥锁以后,结果始终是0。
互斥锁对性能稍微有点开销,所以我们尽可能的将需要加锁的代码减少到最少。

最佳实践:将要锁住的代码片段放入匿名函数

go func(){
	lock.lock()
	defer lock.unlock()
	//your code here 
}()

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go中的读写锁RWMutex发布时间:2022-07-10
下一篇:
Go语言之并发编程(一)发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap