您现在的位置是:群英 > 开发技术 > 编程语言
用Go语言怎么样实现互斥锁,代码是什么
Admin发表于 2022-07-06 17:44:38661 次浏览
这篇文章主要给大家介绍“用Go语言怎么样实现互斥锁,代码是什么”的相关知识,下文通过实际案例向大家展示操作过程,内容简单清晰,易于学习,有这方面学习需要的朋友可以参考,希望这篇“用Go语言怎么样实现互斥锁,代码是什么”文章能对大家有所帮助。



目录
  • 互斥锁
  • 读写互斥锁

先来看这样一段代码,所存在的问题:

var wg sync.WaitGroup
var x int64

func main() {
 wg.Add(2)
 go f()
 go f()
 wg.Wait()
 fmt.Println(x) // 输出:12135
}

func f()  {
 for i:=0;i<10000;i++ {
  x = x+1
 }
 wg.Done() 
}

这里为什么输出是 12135(不同的机器结果不一样),而不是20000。

因为 x 的赋值,总共分为三个步骤:取出x的值、计算x的结果、给x赋值。那么由于对于f函数的调用采用了goroutine协程,所以存在资源竞争的问题,所以有赋值和计算过程中存在脏数据。对于此类的问题,可以采用互斥锁解决:

互斥锁

互斥锁是一种常用的控制共享资源访问的方法,它能够保证同时只有一个goroutine可以访问共享资源。Go语言中使用sync包的Mutex类型来实现互斥锁。

var wg sync.WaitGroup
var x int64
var lock sync.Mutex

func main() {
 wg.Add(2)
 go f()
 go f()
 wg.Wait()
 fmt.Println(x) // 输出:20000
}

func f()  {
 for i:=0;i<10000;i++ {
  lock.Lock() // 加互斥锁
  x = x+1
  lock.Unlock() // 解锁
 }
 wg.Done() 
}

使用互斥锁能够保证同一时间有且只有一个goroutine进入临界区,其他的goroutine则在等待锁;当互斥锁释放后,等待的goroutine才可以获取锁进入临界区,多个goroutine同时等待一个锁时,唤醒的策略是随机的。

读写互斥锁

互斥锁是完全互斥的,但是有很多实际的场景下是读多写少的,当我们并发的去读取一个资源不涉及资源修改的时候是没有必要加锁的,这种场景下使用读写锁是更好的一种选择。读写锁在Go语言中使用sync包中的RWMutex类型。

读写锁分为两种:读锁和写锁。当一个goroutine获取读锁之后,其他的goroutine如果是获取读锁会继续获得锁,如果是获取写锁就会等待;当一个goroutine获取写锁之后,其他的goroutine无论是获取读锁还是写锁都会等待。

var (
 x1 int64
 wg1 sync.WaitGroup
 lock1 sync.Mutex
 rwlock sync.RWMutex
)

func main() {
 startTime := time.Now()
 for i:=0;i<100;i++ {
  wg1.Add(1)
  write()
 }
 for i:=0;i<10000;i++ {
  wg1.Add(1)
  read()
 }
 wg1.Wait()
 fmt.Println(time.Now().Sub(startTime))

 // 互斥锁用时: 973.9304ms
 // 读写互斥锁用时: 718.094ms
}

func read()  {
 defer wg1.Done()
 //lock1.Lock() // 互斥锁
 rwlock.RLock() // 读写互斥锁
 fmt.Println(x1)
 //lock1.Unlock() // 互斥锁
 rwlock.RUnlock() // 读写互斥锁
}

func write()  {
 defer wg1.Done()
 lock1.Lock()
 x1 = x1+1
 lock1.Unlock()
}

以上就是关于“用Go语言怎么样实现互斥锁,代码是什么”的介绍了,感谢各位的阅读,希望文本对大家有所帮助。如果想要了解更多知识,欢迎关注群英网络,小编每天都会为大家更新不同的知识。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

标签: Go互斥锁
相关信息推荐
2022-08-02 17:52:37 
摘要:本文由go语言​教程栏目给大家聊聊Golang进程守护Supervisor,希望对需要的朋友有所帮助!
2022-11-19 17:51:07 
摘要:axios 大家都非常的清楚,一个既可以用于客户端或者 服务端发送http请求的库。但是在前后端联调的时候有的时候会很难受,所以这里我来做一个总结。希望能帮助到有缘人。
2022-04-28 17:48:03 
摘要:给大家带来一篇关于Javascript中import和require用法分析的相关教程文章,内容涉及到import、require、区别、js、import、require、require和import区别、Javascript(es2016) import和require用法和区别详解等相关内容,更多关于Javascript(es2016) import和require用法和区别详解的内容希望能够帮助到大家。
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部