GoLang RWMutex
Dieses Tutorial demonstriert die Verwendung von rwmutex
in GoLang.
GoLang RWMutex
Ein mutex
ist die Abkürzung für gegenseitigen Ausschluss, der verwendet wird, um zu verfolgen, welcher Thread zu einem beliebigen Zeitpunkt auf eine Variable zugegriffen hat. Die Mutexe sind die Datenstruktur, die im sync
-Paket von GoLang bereitgestellt wird.
Die Mutexe
werden verwendet, wenn Parallelität mit dem Go-Code durchgeführt wird. Hier ist ein einfaches Beispiel für die Verwendung von mutex
in GoLang.
package main
import (
"fmt"
"sync"
"time"
)
func EvenNumber(num int) bool {
return num%2 == 0
}
func main() {
num := 2
var DemoMutex sync.Mutex
go func() {
DemoMutex.Lock()
defer DemoMutex.Unlock()
EvenNum := EvenNumber(num)
time.Sleep(5 * time.Millisecond)
if EvenNum {
fmt.Println("The number", num, " is even")
return
}
fmt.Println("The number", num, "is odd")
}()
go func() {
DemoMutex.Lock()
num++
DemoMutex.Unlock()
}()
time.Sleep(time.Second)
}
Der obige Code prüft, ob die Zahl gerade oder ungerade ist. Hier können gleichzeitige Goroutinen
die Daten beschädigen, daher verwenden wir einen mutex
, um Daten zu sperren und zu entsperren, um sie vor einer Beschädigung zu schützen.
Siehe die Ausgabe:
The number 2 is even
mutex
und RWmutex
unterscheiden sich, wobei mutex
ein einfacher Mutex ist und RWmutex
eine Lese-Schreib-Sperre zum gegenseitigen Ausschluss ist. Beim RWMutex
wird der Lock von beliebig vielen Readern oder einem Writer gehalten.
Wenn der Wert für RWMutex
Null ist, handelt es sich um einen entsperrten Mutex. Versuchen wir dasselbe Beispiel mit dem Mutex RWMutex
.
package main
import (
"fmt"
"sync"
"time"
)
func EvenNumber(num int) bool {
return num%2 == 0
}
func main() {
num := 2
var DemoRWM sync.RWMutex
// both goroutines call DemoRWM.Lock() before accessing `num` and then call the DemoRWM.Unlock after they are done
go func() {
DemoRWM.RLock()
defer DemoRWM.RUnlock()
EvenNum := EvenNumber(num)
time.Sleep(5 * time.Millisecond)
if EvenNum {
fmt.Println("The number", num, " is even")
return
}
fmt.Println("The number", num, "is odd")
}()
go func() {
DemoRWM.Lock()
num++
DemoRWM.Unlock()
}()
time.Sleep(time.Second)
}
Wie wir hier sehen können, rufen beide Goroutinen
DemoRWM.Lock()
auf, bevor sie auf num
zugreifen, und rufen dann DemoRWM.Unlock
auf, nachdem sie fertig sind. Der Code verwendet RWMutex
.
Siehe die Ausgabe:
The number 2 is even
Lassen Sie uns ein anderes Beispiel für RWMutex
versuchen, wo RWMutex
allen Lesern erlaubt, gleichzeitig auf die Daten zuzugreifen, und der Schreiber die anderen sperrt.
Siehe das Beispiel:
package main
import (
"fmt"
"sync"
)
func main() {
DemoMap := map[int]int{}
DemoRWM := &sync.RWMutex{}
go LoopWrite(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
// stop the program from exiting must be killed
StopBlock := make(chan struct{})
<-StopBlock
}
func LoopRead(DemoMap map[int]int, DemoRWM *sync.RWMutex) {
for {
DemoRWM.RLock()
for k, v := range DemoMap {
fmt.Println(k, "-", v)
}
DemoRWM.RUnlock()
}
}
func LoopWrite(DemoMap map[int]int, DemoRWM *sync.RWMutex) {
for {
for i := 0; i < 100; i++ {
DemoRWM.Lock()
DemoMap[i] = i
DemoRWM.Unlock()
}
}
}
Wie wir sehen können, erlaubt uns der RWMutex
, read
so oft zu verwenden, wie wir wollen; Die Ausgabe für diesen Code sieht in etwa so aus:
timeout running program
0 - 0
0 - 0
0 - 0
0 - 0
0 - 0
0 - 0
0 - 0
0 - 0
1 - 1
Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.
LinkedIn Facebook