美文网首页
golang-读写锁 sync.RWMutex

golang-读写锁 sync.RWMutex

作者: 爱吃豆包 | 来源:发表于2020-02-04 17:36 被阅读0次

    写解锁会试图唤醒所有因欲进行的读锁定而堵塞的 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-读写锁 sync.RWMutex

          本文链接:https://www.haomeiwen.com/subject/wbtdxhtx.html