Sobes.tech
Middle

Aké typy mutexov poskytuje štandardná knižnica Go?

sobes.tech AI

Odpoveď od AI

Štandardná knižnica jazyka Go poskytuje dva hlavné typy zámkov v balíku sync:

  • sync.Mutex: Základný zámok, ktorý zabezpečuje vzájomné vylúčenie. Môže byť v dvoch stavoch: zamknutý alebo odomknutý. Len jedna gorutina môže držať zámok naraz.
  • sync.RWMutex: Zámok pre čítanie/zápis. Umožňuje viacerým gorutinám súčasne čítať dáta (pomocou RLock), ale len jednej zapisovať (pomocou Lock). Zápis blokuje všetky operácie (ako čítanie, tak zápis).

Hlavné metódy sync.Mutex:

Metóda Popis
Lock() Zamkne zámok. Ak je už zamknutý, volajúca gorutina čaká na jeho odomknutie.
Unlock() Odomkne zámok. Vyvolá sa panic, ak zámok nebol zamknutý volajúcou gorutinou.

Hlavné metódy sync.RWMutex:

Metóda Popis
Lock() Zamkne zámok pre zápis. Blokuje všetky operácie čítania aj zápisu.
Unlock() Odomkne zámok pre zápis. Vyvolá sa panic, ak nebol zamknutý pre zápis.
RLock() Zamkne zámok pre čítanie. Neblokuje iné operácie pre čítanie. Blokuje, ak je zamknutý pre zápis.
RUnlock() Odomkne zámok pre čítanie. Vyvolá sa panic, ak nebol zamknutý pre čítanie.
RLocker() Vráti Locker, ktorý používa RLock a RUnlock.

Príklad použitia sync.Mutex:

package main

import (
	"fmt"
	"sync"
	"time"
)

var counter int
var mutex sync.Mutex

func increment() {
	mutex.Lock() // Zamkneme zámok
	counter++
	fmt.Printf("Counter: %d\n", counter)
	mutex.Unlock() // Odblokujeme zámok
}

func main() {
	for i := 0; i < 10; i++ {
		go increment()
	}
	time.Sleep(time.Second) // Čakáme na dokončenie gorutín
}

Príklad použitia sync.RWMutex:

package main

import (
	"fmt"
	"sync"
	"time"
)

var data string
var rwMutex sync.RWMutex

func readData() {
	rwMutex.RLock() // Zamknutie pre čítanie
	fmt.Printf("Čítanie dát: %s\n", data)
	rwMutex.RUnlock() // Odblokovanie pre čítanie
}

func writeData(newData string) {
	rwMutex.Lock() // Zamknutie pre zápis
	data = newData
	fmt.Printf("Zápis dát: %s\n", data)
	rwMutex.Unlock() // Odblokovanie pre zápis
}

func main() {
	go writeData("Hello")
	time.Sleep(100 * time.Millisecond) // Čakáme na zápis

	for i := 0; i < 5; i++ {
		go readData() // Množstvo súčasných čítaní je povolené
	}

	time.Sleep(time.Second) // Čakáme na dokončenie gorutín
	go writeData("World")
	time.Sleep(100 * time.Millisecond)
	go readData()

	time.Sleep(time.Second)
}