Golang中的RLock()和Lock()有什么区别,以及当我们使用互斥锁时如何有效地使用它们?
答案 0 :(得分:2)
Lock():通过获取锁一次只能执行一次常规例程读/写。
RLock():通过获取锁,多次执行例程可以一次读取(不写入)。
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)
}
1)当一个例程已经获取了一个RLock()时,另一个例程可以获取一个Lock()进行写操作还是必须等待RUnlock()发生?
2)当某人已经为地图获取Lock()时,其他go-routine仍然可以获取RLock()
3)假设我们在这里处理地图,是否有可能发生“并发读取/写入地图”错误?
有关更多说明,请参见以下示例:
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\n",i, b["0"])
time.Sleep(time.Second*3)
fmt.Printf("RLock: from go routine %d: lock released\n",i)
lock.RUnlock()
}(1)
go func(i int) {
lock.Lock()
b["2"] = i
fmt.Printf("Lock: from go routine %d: b = %d\n",i, b["2"])
time.Sleep(time.Second*3)
fmt.Printf("Lock: from go routine %d: lock released\n",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\n",i, b["3"])
time.Sleep(time.Second*3)
fmt.Printf("Lock: from go routine %d: lock released\n",i)
lock.Unlock()
}(3)
go func(i int) {
lock.RLock()
fmt.Printf("RLock: from go routine %d: b = %d\n",i, b["3"])
time.Sleep(time.Second*3)
fmt.Printf("RLock: from go routine %d: lock released\n",i)
lock.RUnlock()
}(4)
<-time.After(time.Second*8)
}
答案 1 :(得分:1)
RWMutex是读取器/写入器互斥锁。锁可以由任意数量的读取器或单个写入器持有。 RWMutex的零值是未锁定的互斥锁。
第一次使用后不得复制RWMutex。
如果goroutine拥有RWMutex进行读取,而另一个goroutine可能会调用Lock,则在释放初始读取锁之前,任何goroutine都不应期望能够获取读取锁。特别是,这禁止了递归读取锁定。这是为了确保锁最终可用。锁定的锁定呼叫被阻止,使新读者无法获得锁定。
互斥锁是互斥锁。互斥锁的零值是未锁定的互斥锁。
golang提供通道是并发控制的最佳实践,因此我认为使用sync.lock的有效方式未使用它,而是使用通道。