Sobes.tech
Middle

Kokius mutex tipus teikia Go standartinė biblioteka?

sobes.tech AI

Atsakymas iš AI

Standartinė Go bibliotekos dalis sync pakete siūlo du pagrindinius užraktų tipus:

  • sync.Mutex: Pagrindinis užraktas, užtikrinantis tarpusavio išimtį. Jis gali būti dviejų būsenų: užrakintas arba atrakintas. Tik viena gorutina gali turėti užraktą vienu metu.
  • sync.RWMutex: Skaitymo/rašymo užraktas. Leidžia kelioms gorutinoms vienu metu skaityti duomenis (RLock), bet tik vienai rašyti (Lock). Rašymas blokuoja visas operacijas (ir skaitymą, ir rašymą).

Pagrindiniai sync.Mutex metodai:

Metodas Aprašymas
Lock() Užrakina užraktą. Jei jis jau užrakintas, kviečianti gorutina laukia jo atlaisvinimo.
Unlock() Atrakina užraktą. Iššaukia panic, jei užraktas nebuvo užrakintas kviečiančios gorutinos.

Pagrindiniai sync.RWMutex metodai:

Metodas Aprašymas
Lock() Užrakina užraktą rašymui. Blokuoja visas skaitymo ir rašymo operacijas.
Unlock() Atrakina užraktą rašymui. Iššaukia panic, jei jis nebuvo užrakintas rašymui.
RLock() Užrakina užraktą skaitymui. Neblokuoja kitų skaitymo operacijų. Blokuojama, jei užrakintas rašymui.
RUnlock() Atrakina užraktą skaitymui. Iššaukia panic, jei jis nebuvo užrakintas skaitymui.
RLocker() Grąžina Locker, kuris naudoja RLock ir RUnlock.

Pavyzdys naudojant sync.Mutex:

package main

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

var counter int
var mutex sync.Mutex

func increment() {
	mutex.Lock() // Užrakinti užraktą
	counter++
	fmt.Printf("Counter: %d\n", counter)
	mutex.Unlock() // Atrakinti užraktą
}

func main() {
	for i := 0; i < 10; i++ {
		go increment()
	}
	time.Sleep(time.Second) // Laukti, kol gorutinos baigsis
}

Pavyzdys naudojant sync.RWMutex:

package main

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

var data string
var rwMutex sync.RWMutex

func readData() {
	rwMutex.RLock() // Skaitymui užrakinti
	fmt.Printf("Duomenų skaitymas: %s\n", data)
	rwMutex.RUnlock() // Atskleisti skaitymą
}

func writeData(newData string) {
	rwMutex.Lock() // Rašymui užrakinti
	data = newData
	fmt.Printf("Duomenų rašymas: %s\n", data)
	rwMutex.Unlock() // Atskleisti rašymą
}

func main() {
	go writeData("Hello")
	time.Sleep(100 * time.Millisecond) // Laukti rašymo

	for i := 0; i < 5; i++ {
		go readData() // Daug vienalaikių skaitymų leidžiama
	}

	time.Sleep(time.Second) // Laukti, kol gorutinos baigsis
	go writeData("World")
	time.Sleep(100 * time.Millisecond)
	go readData()

	time.Sleep(time.Second)
}