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

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 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看