3.21 Go之锁(二)

3.21 Go之锁(二)

锁的种类

  • 互斥锁(sync.Mutex)

  • 读写互斥锁(sync.RWMutex)

Go提供的函数

gosync包下提供了两种类型:

  1. sync.Mutex

  2. sync.RWMutex

Mutex
Mutex的概念

最简单的锁定

特点:

当一个goroutine获得Mutex后,其他goroutine只能等待该goroutine释放该Mutex

RWMutex
RWMutex的概念

单写多读模型

概念:

  1. 读锁占用的情况下,阻止写不阻止读

  2. 写锁会阻止其他的读、写过程

示例代码:

package main

import (
   "fmt"
   "sync"
)

/*
设计Mutex的实例
*/
// 声明变量
var (
   // 声明逻辑中使用到的变量
   countNo2 int

   // 声明变量的互斥锁
   countGuard sync.Mutex
)

// 获取变量
func GetCount() int {
   // 锁定
   /*
   对 countGuard 互斥量进行加锁。一旦 countGuard 发生加锁,如果另外一个 goroutine 尝试继续加锁时将会发生阻塞,直到这个 countGuard 被解锁。
    */
   countGuard.Lock()

   // 函数接触时的处理
   defer countGuard.Unlock()

   // 返回变量
   return countNo2
}

// 设置变量
func SetCount(c int) {
   // 上锁
   countGuard.Lock()

   // 赋值
   countNo2 = c

   // 解锁
   countGuard.Unlock()
}

// main函数中调用
func main() {
   // 并发安全设置
   SetCount(1)

   // 打印并发安全的获取
   fmt.Println(GetCount())
}

在读多写少的环境可以优先使用读写互斥锁(RWMutex),因为它更高效.

var (
   // 声明逻辑中使用到的变量
   countNo2 int

   // 声明变量的互斥锁
   countGuard sync.RWMutex
)

// 获取变量
func GetCount() int {
   // 锁定
   /*
   对 countGuard 互斥量进行加锁。一旦 countGuard 发生加锁,如果另外一个 goroutine 尝试继续加锁时将会发生阻塞,直到这个 countGuard 被解锁。
    */
   //countGuard.Lock()
   // 使用读写互斥锁
   countGuard.RLock()

   // 函数接触时的处理
   /*
   与读模式加锁对应的,使用读模式解锁。
    */
   defer countGuard.RUnlock()

   // 返回变量
   return countNo2
}
总结

RWMutex类型其实组合了Mutexn

共同点:

任何一个Lock()RLock()均需要保证对应有Unlock()RUnlock()调用与之对应,否则可能导致等待该锁的所有 goroutine处于饥饿状态,甚至可能导致死锁

posted @   俊king  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示