GoLang RWMutex

Sheeraz Gul 20 Juni 2023
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 Gul avatar Sheeraz Gul avatar

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