GoLang RWMutex

Sheeraz Gul 20 junio 2023
GoLang RWMutex

Este tutorial demuestra cómo usar rwmutex en GoLang.

GoLang RWMutex

Un mutex es la abreviatura de exclusión mutua que se utiliza para rastrear qué subproceso ha accedido a una variable en cualquier momento. Los mutexes son la estructura de datos provista en el paquete sync de GoLang.

Los mutexes se utilizan al realizar concurrencia utilizando el código Go. Aquí hay un ejemplo simple del uso de mutex en 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)
}

El código anterior verifica si el número es par o impar. Aquí, las gorrutinas concurrentes pueden corromper los datos, por lo que usamos un mutex para bloquear y desbloquear datos para evitar que se dañen.

Ver la salida:

The number 2  is even

El mutex y RWmutex son diferentes donde mutex es un simple mutex, y RWmutex es un bloqueo de exclusión mutua de lector-escritor. Con el RWMutex, el bloqueo lo mantiene un número arbitrario de lectores o un escritor.

Cuando el valor de RWMutex es cero, es un mutex desbloqueado. Probemos el mismo ejemplo con el 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)
}

Como podemos ver aquí, ambas goroutines llaman a DemoRWM.Lock() antes de acceder a num y luego llaman a DemoRWM.Unlock una vez que terminan. El código usa RWMutex.

Ver la salida:

The number 2  is even

Probemos otro ejemplo para RWMutex donde RWMutex permite que todos los lectores accedan a los datos simultáneamente, y el escritor bloqueará a los demás.

Ver el ejemplo:

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()
        }
    }
}

Como vemos, el RWMutex nos permite usar el leer tantas veces como queramos; la salida de este código será algo como esto:

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