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

Golang中的RLock()和Lock()有什么区别?,go,mutex,Go,Mutex,Golang中RLock()和Lock()的区别是什么?当我们使用互斥锁时,如何有效地使用它们?RWMutex是读写互斥锁。锁可以由任意数量的读卡器或单个写入器持有。RWMutex的零值是未锁定的mutex 首次使用后不得复制RWMutex 如果一个goroutine持有一个用于读取的RWMutex,而另一个goroutine可能调用Lock,那么在释放初始读取锁之前,任何goroutine都不应该期望能够获取读取锁。特别是,这禁止递归读取锁定。这是为了确保锁最终可用;被阻止的锁调用会使新读卡器

Golang中RLock()和Lock()的区别是什么?当我们使用互斥锁时,如何有效地使用它们?

RWMutex是读写互斥锁。锁可以由任意数量的读卡器或单个写入器持有。RWMutex的零值是未锁定的mutex

首次使用后不得复制RWMutex

如果一个goroutine持有一个用于读取的RWMutex,而另一个goroutine可能调用Lock,那么在释放初始读取锁之前,任何goroutine都不应该期望能够获取读取锁。特别是,这禁止递归读取锁定。这是为了确保锁最终可用;被阻止的锁调用会使新读卡器无法获取锁

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\n",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\n",i, b)
            time.Sleep(time.Second)
            lock.RUnlock()
        }(i)
    }

    <-time.After(time.Second*10)
}

互斥锁是互斥锁。互斥体的零值是未锁定的互斥体

golang提供的通道是并发控制的最佳实践,因此我认为使用sync.lock的有效方法不是使用它,而是使用通道

Lock():通过获取锁,一次只能读取/写入一个go例程

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\n",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\n",i, b)
            time.Sleep(time.Second)
            lock.RUnlock()
        }(i)
    }

    <-time.After(time.Second*10)
}
RLock():多个go例程可以通过获取锁一次读取(而不是写入)

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\n",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\n",i, b)
            time.Sleep(time.Second)
            lock.RUnlock()
        }(i)
    }

    <-time.After(time.Second*10)
}
主程序包
进口(
“fmt”
“同步”
“时间”
)
func main(){
a:=0
lock:=sync.RWMutex{}
对于i:=1;i<10;i++{
go func(i int){
lock.lock()
fmt.Printf(“锁定:从go例程%d:a=%d\n”,i,a)
时间。睡眠(时间。秒)
lock.Unlock()
}(一)
}
b:=0
对于i:=11;i<20;i++{
go func(i int){
lock.RLock()
fmt.Printf(“RLock:from-go例程%d:b=%d\n”,i,b)
时间。睡眠(时间。秒)
lock.RUnlock()
}(一)
}

感谢您的回答,我有一些问题1)当一个go例程已经获取了RLock()时,另一个go例程是否可以获取用于写入的锁(),或者它必须等到RUnlock()才可以发生了什么?2)如果有人已经获得了map的Lock(),那么其他go例程是否仍然可以获得RLock()3)假设我们正在处理map,是否有可能“并发读取/写入映射”错误是否会出现?