老男孩教育专注IT教育10余年,只培养IT技术精英

全国免费咨询电话(渠道合作):400-609-2893

跟老男孩学GO语言之读写锁

老男孩IT教育

常见问题

2021年5月24日 15:54

RWMutex是一个读写锁,该锁可以加多个读锁或者一个写锁,其经常用于读次数远远多于写次数的场景。

  RWMutex是一个读写锁,该锁可以加多个读锁或者一个写锁,其经常用于读次数远远多于写次数的场景。

func (rw *RWMutex) Lock()

  Lock方法将rw锁定为写入状态,禁止其他线程读取或者写入。如果在添加写锁之前已经有其他的读锁和写锁,则lock就会阻塞直到该锁可用,为确保该锁最终可用,已阻塞的 Lock 调用会从获得的锁中排除新的读取器,即写锁权限高于读锁,有写锁时优先进行写锁定。

func (rw *RWMutex) Unlock()

  Unlock方法解除rw的写入锁状态,如果m未加写入锁会导致运行时错误。

func (rw *RWMutex) RLock()

  RLock方法将rw锁定为读取状态,禁止其他线程写入,但不禁止读取。

func (rw *RWMutex) RUnlock()

  Runlock方法解除rw的读取锁状态,如果m未加读取锁会导致运行时错误。

  读写锁的写锁只能锁定一次,解锁前不能多次锁定,读锁可以多次,但读解锁次数最多只能比读锁次数多一次,一般情况下我们不建议读解锁次数多余读锁

  读写锁应用

  读多写少的情况,用读写锁, 协程同时在操作读。

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

var rwLock sync.RWMutex

func main() {
    m := make(map[int]int, 5)
    m[1] = 10
    m[2] = 10
    m[3] = 10
    m[4] = 10
    m[5] = 10
    for i := 0; i < 2; i++ {
        go func() {
            rwLock.Lock()
            m[5] = rand.Intn(100)
            rwLock.Unlock()
        }()
    }
    for i := 0; i < 10; i++ {
        go func() {
            rwLock.RLock()
            fmt.Println(m)
            rwLock.RUnlock()
        }()
    }
    time.Sleep(time.Second * 2)
}

  当RUnlock()在RLock()之前使用时便会报错,实例如下:

package main

import (
    "fmt"
    "sync"
)

func main() {
    RWLock := new(sync.RWMutex)
    RWLock.RUnlock()
    fmt.Println("hello RWMutex")
    RWLock.RLock()
}

  运行错误:

fatal error: sync: RUnlock of unlocked RWMutex

  0基础学习GO语言,难度高?不好学?欢迎来老男孩教育试听,2021年全新课程升级,满足企业用人所需。

  推荐阅读:

  Python32位和64位有何区别?老男孩Python课程怎么样?

  Python学习之Tensorflow软件库

  Python对比PHP有哪些优势?老男孩Python学习多久?

本文经授权发布,不代表老男孩教育立场。如若转载请联系原作者。