dongyun4010 2018-11-22 09:36
浏览 4055
已采纳

Golang中的RLock()和Lock()有什么区别?

what is the difference between RLock() and Lock() in Golang and how they can be used efficiently when we use mutex Lock ?

  • 写回答

2条回答 默认 最新

  • dopcpc9207 2018-11-22 10:50
    关注

    Lock(): only one go routine read/write at a time by acquiring the lock.

    RLock(): multiple go routine can read(not write) at a time by acquiring the lock.

    package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    func main() {
    
        a := 0
    
        lock := sync.RWMutex{}
    
        for i := 1; i < 10; i++ {
            go func(i int) {
                lock.Lock()
                fmt.Printf("Lock: from go routine %d: a = %d
    ",i, a)
                time.Sleep(time.Second)
                lock.Unlock()
            }(i)
        }
    
        b := 0
    
        for i := 11; i < 20; i++ {
            go func(i int) {
                lock.RLock()
                fmt.Printf("RLock: from go routine %d: b = %d
    ",i, b)
                time.Sleep(time.Second)
                lock.RUnlock()
            }(i)
        }
    
        <-time.After(time.Second*10)
    }
    

    1) When a go-routine has already acquired a RLock(), can another go-routine acquire a Lock() for write or it has to wait until RUnlock() happens?

    • To acquire a Lock() for write it has to wait until RUnlock()

    2) What happens when someone already acquired Lock() for map ,will other go-routine can still get RLock()

    • if someone X already acquired Lock(), then other go-routine to get RLock() will have to wait until X release lock (Unlock())

    3) Assuming we are dealing with Maps here, is there any possibility of "concurrent read/write of Map" error can come?

    • Map is not thread safe. so "concurrent read/write of Map" can cause error.

    See following example for more clarification:

    package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    func main() {
        lock := sync.RWMutex{}
    
        b := map[string]int{}
        b["0"] = 0
    
        go func(i int) {
            lock.RLock()
            fmt.Printf("RLock: from go routine %d: b = %d
    ",i, b["0"])
            time.Sleep(time.Second*3)
            fmt.Printf("RLock: from go routine %d: lock released
    ",i)
            lock.RUnlock()
        }(1)
    
        go func(i int) {
            lock.Lock()
            b["2"] = i
            fmt.Printf("Lock: from go routine %d: b = %d
    ",i, b["2"])
            time.Sleep(time.Second*3)
            fmt.Printf("Lock: from go routine %d: lock released
    ",i)
            lock.Unlock()
        }(2)
    
        <-time.After(time.Second*8)
    
        fmt.Println("*************************************8")
    
        go func(i int) {
            lock.Lock()
            b["3"] = i
            fmt.Printf("Lock: from go routine %d: b = %d
    ",i, b["3"])
            time.Sleep(time.Second*3)
            fmt.Printf("Lock: from go routine %d: lock released
    ",i)
            lock.Unlock()
        }(3)
    
        go func(i int) {
            lock.RLock()
            fmt.Printf("RLock: from go routine %d: b = %d
    ",i, b["3"])
            time.Sleep(time.Second*3)
            fmt.Printf("RLock: from go routine %d: lock released
    ",i)
            lock.RUnlock()
        }(4)
    
        <-time.After(time.Second*8)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)
  • ¥20 怎么在stm32门禁成品上增加查询记录功能
  • ¥15 Source insight编写代码后使用CCS5.2版本import之后,代码跳到注释行里面
  • ¥50 NT4.0系统 STOP:0X0000007B
  • ¥15 想问一下stata17中这段代码哪里有问题呀
  • ¥15 flink cdc无法实时同步mysql数据