iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Golang的锁机制与使用技巧是什么
  • 846
分享到

Golang的锁机制与使用技巧是什么

2023-06-30 17:06:52 846人浏览 安东尼
摘要

本篇内容主要讲解“golang的锁机制与使用技巧是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Golang的锁机制与使用技巧是什么”吧!1. sync.Mutex详解sync.Mutex是

本篇内容主要讲解“golang机制与使用技巧是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习Golang的锁机制与使用技巧是什么”吧!

1. sync.Mutex详解

sync.Mutex是Go中的互斥锁,通过.lock()方法上锁,.unlock()方法解锁。需要注意的是,因为Go函数值传递的特点,sync.Mutex通过函数传递时,会进行一次拷贝,所以传递过去的锁是一把全新的锁,大家在使用时要注意这一点,另外sync.Mutex是非重入锁,这一点要与Java中的锁区分。

type Mutex {    state int32    sema  uint32}

上面数据结构中的state最低三位分别表示 mutexLocked、mutexWoken 和 mutexStarving,剩下的位置用来表示当前有多少个 Goroutine 等待互斥锁的释放:

32                                               3             2             1             0  |                                               |             |             |             |  |                                               |             |             |             |  v-----------------------------------------------v-------------v-------------v-------------+  |                                               |             |             |             v  |                 waitersCount                  |mutexStarving| mutexWoken  | mutexLocked |  |                                               |             |             |             |  +-----------------------------------------------+-------------+-------------+-------------+
  • mutexLocked — 表示互斥锁的锁定状态;

  • mutexWoken — 表示从正常模式被从唤醒;

  • mutexStarving — 当前的互斥锁进入饥饿状态;

  • waitersCount — 当前互斥锁上等待的 goroutine 个数;

2. RWMutex详解

type RWMutex struct {w           Mutex  // 复用互斥锁writerSem   uint32 // 写锁监听读锁释放的信号量readerSem   uint32 // 读锁监听写锁释放的信号量readerCount int32  // 当前正在执行读操作的数量readerWait  int32  // 当写操作被阻塞时,需要等待读操作完成的个数}
  • 读操作如何防止并发读写问题的?

RLock(): 申请读锁,每次执行此函数后,会对readerCount++,此时当有写操作执行Lock()时会判断readerCount>0,就会阻塞。

RUnLock(): 解除读锁,执行readerCount–,释放信号量唤醒等待写操作的goroutine。

  • 写操作如何防止并发读写、并发写写问题?

Lock(): 申请写锁,获取互斥锁,此时会阻塞其他的写操作。并将readerCount 置为 -1,当有读操作进来,发现readerCount = -1, 即知道有写操作在进行,阻塞。

Unlock(): 解除写锁,会先通知所有阻塞的读操作goroutine,然后才会释放持有的互斥锁。

  • 写操作的饥饿问题?

这是由于写操作要等待读操作结束后才可以获得锁,而写操作在等待期间可能还有新的读操作持续到来,如果写操作等待所有读操作结束,很可能会一直阻塞,这种现象称之为写操作被饿死。

通过RWMutex结构体中的readerWait属性可完美解决这个问题。

当写操作到来时,会把RWMutex.readerCount值拷贝到RWMutex.readerWait中,用于标记排在写操作前面的读者个数。

前面的读操作结束后,除了会递减RWMutex.readerCount,还会递减RWMutex.readerWait值,当RWMutex.readerWait值变为0时唤醒写操作。

3. sync.Map详解

一般情况下解决并发读写 map 的思路是加一把大锁,或者把一个 map 分成若干个小 map,对 key 进行哈希,只操作相应的小 map。前者锁的粒度比较大,影响效率;后者实现起来比较复杂,容易出错。

而使用 sync.map 之后,对 map 的读写,不需要加锁。并且它通过空间换时间的方式,使用 read 和 dirty 两个 map 来进行读写分离,降低锁时间来提高效率。

type Map struct {mu Mutexread atomic.Value // readOnlydirty map[interface{}]*entrymisses int}// readOnly is an immutable struct stored atomically in the Map.read field.type readOnly struct {m       map[interface{}]*entryamended bool // true if the dirty map contains some key not in m.}type entry struct {p unsafe.Pointer // *interface{}}

Golang的锁机制与使用技巧是什么

在进行读操作的时候,会先在read中找,没有命中的话会锁住dirty并且寻找,如果找到了miss计数+1,超过阈值时将dirty赋值给read;

在进行添加操作时,直接在dirty中添加;

在进行修改操作时,先改read,再改dirty;

在进行删除操作时,将read中加上amended标记,dirty中直接删除。

4. 原子操作 atomic.Value

愿此操作的底层是靠 MESI 缓存一致性协议来维持的。

Go的 atomic.Value 需要注意应该放入只读对象。

//atomic.Value源码type Value struct {v interface{} // 所以可以存储任何类型的数据}// 空 interface{} 的内部表示格式,作用是将interface{}类型分解,得到其中两个字段type ifaceWords struct {typ  unsafe.Pointerdata unsafe.Pointer}// 取数据就是正常走流程func (v *Value) Load() (x interface{}) {vp := (*ifaceWords)(unsafe.Pointer(v))typ := LoadPointer(&vp.typ)if typ == nil || uintptr(typ) == ^uintptr(0) {// 第一次还没写入return nil}  // 构造新的interface{}返回出去data := LoadPointer(&vp.data)xp := (*ifaceWords)(unsafe.Pointer(&x))xp.typ = typxp.data = datareturn}// 写数据(如何保证数据完整性)func (v *Value) Store(x interface{}) {if x == nil {panic("sync/atomic: store of nil value into Value")}  // 绕过 Go 语言类型系统的检查,与任意的指针类型互相转换vp := (*ifaceWords)(unsafe.Pointer(v)) // 旧值xp := (*ifaceWords)(unsafe.Pointer(&x)) // 新值for { // 配合CompareAndSwap达到乐观锁的功效typ := LoadPointer(&vp.typ)if typ == nil { // 第一次写入runtime_procPin() // 禁止抢占if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(^uintptr(0))) {runtime_procUnpin() // 没有抢到锁,说明已经有别的线程抢先完成赋值,重新进入循环continue}// 首次赋值StorePointer(&vp.data, xp.data)StorePointer(&vp.typ, xp.typ)runtime_procUnpin() // 写入成功,解除占用状态return}if uintptr(typ) == ^uintptr(0) {// 第一次写入还未完成,继续等待continue}// 两次需要写入相同类型if typ != xp.typ {panic("sync/atomic: store of inconsistently typed value into Value")}StorePointer(&vp.data, xp.data)return}}// 禁止抢占,标记当前G在M上不会被抢占,并返回当前所在P的ID。func runtime_procPin()// 解除G的禁止抢占状态,之后G可被抢占。func runtime_procUnpin()

5. 使用小技巧

  • 减小临界区域(减少锁的持有时间)

var m sync.Mutexfunc DoSth() {    // do sth2    func() {       u.lock()       defer m.unlock()       // do sth3    }()     // do sth4}

如上所示,如果do sth4中是很费时的io操作,使用这个技巧可以将临界区减小,提高性能,不过,如果本身临界区就不大,锁操作后续没有什么费时操作,那么也就没有必要这样操作了。

  • 减小锁的粒度

高并发场景下,用锁的数量来换取并发效率,类似于java中ConcurrentHashMap的分段锁思想,增加锁的数量,减少一把锁控制的数据量。

  • 读写分离(读写锁): RWMutex,sync.Map

在读多写少的情景下,可以使用读写锁,提高读操作的并发性能。

  • 使用原子操作

原子操作是CPU指令级的操作,不会触发g调度机制,不阻塞执行流。

到此,相信大家对“Golang的锁机制与使用技巧是什么”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

您可能感兴趣的文档:

--结束END--

本文标题: Golang的锁机制与使用技巧是什么

本文链接: https://www.lsjlt.com/news/330685.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Golang的锁机制与使用技巧是什么
    本篇内容主要讲解“Golang的锁机制与使用技巧是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Golang的锁机制与使用技巧是什么”吧!1. sync.Mutex详解sync.Mutex是...
    99+
    2023-06-30
  • Golang的锁机制与使用技巧小结
    目录1. sync.Mutex详解2. RWMutex详解3. sync.Map详解4. 原子操作 atomic.Value5. 使用小技巧1. sync.Mutex详解 sync....
    99+
    2024-04-02
  • Golang中锁机制的性能优化技巧
    在Golang中,锁(Mutex)是一种常用的并发控制机制,但在某些情况下,使用锁可能会导致性能问题。以下是一些Golang中锁机制...
    99+
    2023-10-08
    Golang
  • MongoDB的并发控制与锁机制是什么
    MongoDB使用乐观并发控制(Optimistic Concurrency Control)来处理并发操作。在MongoDB中,并...
    99+
    2024-05-07
    MongoDB
  • Golang的锁机制使用及说明
    目录踩坑点互斥锁 Mutex读写锁 RWMutex谨防锁拷贝查看数据竞争总结golang中的锁分为互斥锁、读写锁、原子锁即原子操作。 在 Golang 里有专门的方法来实现锁,就是 ...
    99+
    2023-02-16
    Golang锁机制 锁机制 Golang锁
  • Golang方法的使用与优化技巧
    Golang方法的使用与优化技巧 在Go语言编程中,方法是一种特殊类型的函数,它是一个与对象关联的函数。本文将通过具体的代码示例介绍Golang方法的使用和优化技巧,让读者更好地掌握这...
    99+
    2024-02-23
    使用 优化技巧 golang方法 go语言
  • 什么是MySQL锁机制
    本篇内容主要讲解“什么是MySQL锁机制”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“什么是MySQL锁机制”吧!无论什么时候,只要存在多个连接在同一时刻修改数...
    99+
    2024-04-02
  • ADO.NET使用技巧是什么
    本篇内容介绍了“ADO.NET使用技巧是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!打开连接后,ADO.NET技巧使本地OLE DB向...
    99+
    2023-06-17
  • PostgreSQL中的锁机制是什么
    PostgreSQL中的锁机制是用来控制并发访问数据库中数据的方式。它可以防止多个会话同时对同一数据进行修改,从而避免数据不一致的问...
    99+
    2024-04-02
  • MySQL中的锁机制是什么
    这篇“MySQL中的锁机制是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MySQL中的锁机制是什么”文章吧。一.概述锁...
    99+
    2023-07-05
  • Java中的锁机制是什么
    今天小编给大家分享一下Java中的锁机制是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Java中的锁机制是保证多线程并...
    99+
    2023-07-05
  • Golang的GC机制是什么
    这篇文章主要介绍“Golang的GC机制是什么”,在日常操作中,相信很多人在Golang的GC机制是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang的GC机制是什么”的疑惑有所帮助!接下来,请跟...
    99+
    2023-07-05
  • MySQL加锁机制是什么
    这篇文章主要介绍MySQL加锁机制是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前言在数据库中设计锁的目的是为了处理并发问题,在并发对资源进行访问时,数据库要合理控制对资源的访问规则。而锁就是用来实现这些访问规...
    99+
    2023-06-29
  • mysql锁机制的概念是什么
    本文小编为大家详细介绍“mysql锁机制的概念是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“mysql锁机制的概念是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。My...
    99+
    2024-04-02
  • 数据库的锁机制是什么
    数据库的锁机制是一种用于保护数据库的一致性和并发操作的机制。它确保数据库中的数据在被多个并发事务访问和修改时保持一致性,避免数据的混...
    99+
    2023-09-20
    数据库
  • Golang中同步机制的性能调优技巧与经验分享
    在Golang中,使用同步机制(如互斥锁,读写锁等)是保证并发安全的重要手段。然而,不正确的同步机制使用可能导致性能问题。下面是一些...
    99+
    2023-10-08
    Golang
  • Golang单元测试中的技巧是什么
    这篇文章主要讲解了“Golang单元测试中的技巧是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang单元测试中的技巧是什么”吧!打桩测试当我们在编写单元测试的时候,有时我们非常想...
    99+
    2023-07-05
  • MySQL锁机制原理是什么
    这篇文章主要介绍“MySQL锁机制原理是什么”,在日常操作中,相信很多人在MySQL锁机制原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL锁机制原理是什么”...
    99+
    2024-04-02
  • 分享MySQL中锁的使用技巧
    MySQL 锁的使用技巧分享随着数据库应用的日益广泛,对数据库的并发控制和数据完整性要求也越来越高。在MySQL数据库中,锁是一种重要的并发控制手段,可以有效地保护数据的完整性和一致性。本文将对MySQL锁的使用技巧进行详细分享,并提供具体...
    99+
    2023-12-21
    MySQL 技巧
  • Kubernetes中锁机制的设计与实现方法是什么
    这篇文章主要讲解了“Kubernetes中锁机制的设计与实现方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Kubernetes中锁机制的设计与实现...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作