go-锁机制

林桉 · · 938 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Golang中的锁机制主要包含互斥锁和读写锁

互斥锁

互斥锁是一种简单的加锁的方法来控制对共享资源的访问,互斥锁只有两种状态,即上锁( lock )和解锁( unlock )。

func mutex() { 
var mu
sync.Mutex mu.Lock() 
fmt.Println("locked")
mu.Unlock() 
}

defer实现

func mutex() {
var mu 
sync.Mutex mu.Lock() 
defer mu.Unlock() 
fmt.Println("locked")
 }

【互斥锁的特点】:

  1. 原子性:把一个互斥量锁定为一个原子操作,这意味着操作系统(或pthread函数库)保证了如果一个线程锁定了一个互斥量,没有其他线程在同一时间可以成功锁定这个互斥量;

  2. 唯一性:如果一个线程锁定了一个互斥量,在它解除锁定之前,没有其他线程可以锁定这个互斥量;

  3. 非繁忙等待:如果一个线程已经锁定了一个互斥量,第二个线程又试图去锁定这个互斥量,则第二个线程将被挂起(不占用任何cpu资源),直到第一个线程解除对这个互斥量的锁定为止,第二个线程则被唤醒并继续执行,同时锁定这个互斥量。

  4. 互斥锁是开箱即用的,只需要申明sync.Mutex即可直接使用

  5. 互斥锁应该是成对出现,在同步语句不可以再对锁加锁,看下面的示例:

func mutex() { 
var mu 
sync.Mutex mu.Lock() 
fmt.Println("parent locked") 
mu.Lock() 
fmt.Println("sub locked") 
mu.Unlock() 
mu.Unlock()
}

此时则会出现fatal error: all goroutines are asleep - deadlock!错误

读写锁

读写锁和互斥锁不同之处在于,可以分别针对读操作和写操作进行分别锁定,这样对于性能有一定的提升。 读写锁,对于多个写操作,以及写操作和读操作之前都是互斥的这一点基本等同于互斥锁。 但是对于同时多个读操作之前却非互斥关系,这也是相读写锁性能高于互斥锁的主要原因。

  • 特点
    开箱即用
    var rwm = sync.RWMutex
  • 写锁定和写解锁
    rwm.Lock()
    rwm.Unlock()
  • 读锁定和读解锁
    rwm.RLock()
    rwm.RUnlock()
  • 读写锁的读锁和写锁不能交叉相互解锁,否则会发生panic
func rwMutex() {
 var rwm sync.RWMutex
 rwm.Lock()
 fmt.Println("locked")
 rwm.RUnlock()
}
  • 对于读写锁,同一资源可以同时有多个读锁定

在goroutine中,写解锁会试图唤醒所有想要进行读锁定而被阻塞的goroutine。

而读解锁会在已无任何读锁定的情况下,试图唤醒一个想进行写锁定而被阻塞的goroutine。

func rwMutex() {
 var rwm sync.RWMutex

 for i := 0; i <= 2; i++ {
 go func(i int) {
 fmt.Printf("go(%d) start lock\n", i)
 rwm.RLock()
 fmt.Printf("go(%d) locked\n", i)
 time.Sleep(time.Second * 2)
 rwm.RUnlock()
 fmt.Printf("go(%d) unlock\n", i)
 }(i)
 }
 // 先sleep一小会,保证for的goroutine都会执行
 time.Sleep(time.Microsecond * 100)
 fmt.Println("main start lock")
 // 当子进程都执行时,且子进程所有的资源都已经Unlock了
 // 父进程才会执行
 rwm.Lock()
 fmt.Println("main locked")
 time.Sleep(time.Second)
 rwm.Unlock()
}

参考

互斥锁、条件锁、读写锁以及自旋锁:https://www.zhihu.com/question/66733477
https://www.cnblogs.com/cangqinglang/p/13328217.html
https://laravelacademy.org/post/19901.html


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:林桉

查看原文:go-锁机制

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

938 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传