golang-读写锁

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

写解锁会试图唤醒所有因欲进行的读锁定而堵塞的 goroutine
读解锁只会试图唤醒一个因欲进行写锁定而被堵塞的 goroutine

package main

import (
    "fmt"
    "sync"
    "time"
)

// 读写锁
/**
    sync.RWMutex 读写锁类型
    提供的函数:
        写锁:加锁/解锁
            func (*RWMutex) Lock()
            func (RWmutex) UnLock()
        读锁:加锁/解锁
            func (*RWMutex) RLock()
            func (RWmutex) RUnLock()

    写解锁会试图唤醒所有因欲进行的读锁定而堵塞的 goroutine
    读解锁只会试图唤醒一个因欲进行写锁定而被堵塞的 goroutine


**/

func main() {
    var rwm sync.RWMutex
    for i := 0; i < 3; i++ {
        go func(i int) {
            fmt.Printf("准备开始读取。。。,尝试获取读锁定![%d]\n", i)
            rwm.RLock()
            fmt.Printf("获取到读锁定,开始读取。。。[%d]\n", i)
            fmt.Printf("正在读取中,[%d]\n", i)
            time.Sleep(time.Second * 2)
            fmt.Printf("读取完成,开始释放读锁![%d]\n", i)
            rwm.RUnlock()
            fmt.Printf("读锁释放完成![%d]\n", i)
        }(i)
    }

    time.Sleep(time.Microsecond * 1000)
    fmt.Printf("主函数准备尝试获取写锁定![%s]\n", "main")
    rwm.Lock()
    fmt.Printf("主函数获取到写锁定![%s]\n", "main")
}

输出

准备开始读取。。。,尝试获取读锁定![1]
获取到读锁定,开始读取。。。[1]
正在读取中,[1]
准备开始读取。。。,尝试获取读锁定![0]
获取到读锁定,开始读取。。。[0]
正在读取中,[0]
准备开始读取。。。,尝试获取读锁定![2]
获取到读锁定,开始读取。。。[2]
正在读取中,[2]
主函数准备尝试获取写锁定![main]
读取完成,开始释放读锁![2]
读锁释放完成![2]
读取完成,开始释放读锁![0]
读锁释放完成![0]
读取完成,开始释放读锁![1]
读锁释放完成![1]
主函数获取到写锁定![main]

根据这个结果,可以看出:

  1. 读锁和写锁是互斥的!
  2. 读锁可以多个读锁并发读!

只有在所有的读锁释放后,写锁才能获取到!

另外一个指针函数

    // 通过 sync.RWMutex 的指针函数获取锁本身(读锁)

    var rwm sync.RWMutex
    // 获取读写锁本身
    locker := rwm.RLocker()
    // 读加锁
    locker.Lock()
    // 读解锁
    locker.Unlock()

这个 rwm.RLocker() 是实现了sync.Locker 接口类型,调用这个 rwm.RLocker() 函数后,实际上获取的是读写锁本身,但是所携带的locker.Lock()locker.Unlock() 的操作却是指的读锁定读解锁!也就是说这个操作只针对 读锁

附上源码

func (rw *RWMutex) RLocker() Locker {
    return (*rlocker)(rw)
}

type rlocker RWMutex

func (r *rlocker) Lock()   { (*RWMutex)(r).RLock() }
func (r *rlocker) Unlock() { (*RWMutex)(r).RUnlock() }

Lock() 和 Unlock() 指的都是读加锁 和 读解锁 操作!


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

本文来自:简书

感谢作者:爱吃豆包

查看原文:golang-读写锁

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

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