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) Когда подпрограмма go уже получила RLock (), может ли другая подпрограмма go получить Lock () для записи или она имеетждать, пока не произойдет RUnlock ()?
- Чтобы получить блокировку () для записи, нужно подождать, пока RUnlock ()
2) Что происходит, когда кто-то уже приобрелLock () для карты, будет ли другая подпрограмма go по-прежнему получать RLock ()
- , если кто-то X уже приобрел Lock (), тогда другой подпрограмме для получения RLock () придется подождать, покаБлокировка разблокировки X (Unlock ())
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)
}