Sobes.tech
Middle

Quali tipi di mutex fornisce la libreria standard di Go?

sobes.tech AI

Risposta dell'AI

La libreria standard di Go fornisce due tipi principali di mutex nel pacchetto sync:

  • sync.Mutex: Mutex di base che garantisce esclusione mutua. Può essere in due stati: bloccato o sbloccato. Solo una goroutine può mantenere il blocco in un dato momento.
  • sync.RWMutex: Mutex per lettura/scrittura. Permette a molte goroutines di leggere contemporaneamente (ottenendo RLock), ma solo a una di scrivere (ottenendo Lock). La scrittura blocca tutte le operazioni (sia di lettura che di scrittura).

Metodi principali di sync.Mutex:

Metodo Descrizione
Lock() Blocca il mutex. Se già bloccato, la goroutine chiamante si blocca fino a quando non viene rilasciato.
Unlock() Sblocca il mutex. Genera un panic se il mutex non era bloccato dalla goroutine chiamante.

Metodi principali di sync.RWMutex:

Metodo Descrizione
Lock() Blocca il mutex per scrittura. Blocca tutte le operazioni di lettura e scrittura.
Unlock() Sblocca il mutex per scrittura. Genera un panic se il mutex non era bloccato per scrittura.
RLock() Blocca il mutex per lettura. Non blocca altre operazioni di lettura. Si blocca se c'è un lock di scrittura.
RUnlock() Sblocca il mutex per lettura. Genera un panic se il mutex non era bloccato per lettura.
RLocker() Restituisce un Locker che utilizza RLock e RUnlock.

Esempio di utilizzo di sync.Mutex:

package main

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

var counter int
var mutex sync.Mutex

func increment() {
	mutex.Lock() // Blocca il mutex
	counter++
	fmt.Printf("Counter: %d\n", counter)
	mutex.Unlock() // Sblocca il mutex
}

func main() {
	for i := 0; i < 10; i++ {
		go increment()
	}
	time.Sleep(time.Second) // Dà tempo alle goroutine di finire
}

Esempio di utilizzo di sync.RWMutex:

package main

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

var data string
var rwMutex sync.RWMutex

func readData() {
	rwMutex.RLock() // Blocca per lettura
	fmt.Printf("Leggendo dati: %s\n", data)
	rwMutex.RUnlock() // Sblocca per lettura
}

func writeData(newData string) {
	rwMutex.Lock() // Blocca per scrittura
	data = newData
	fmt.Printf("Scrivendo dati: %s\n", data)
	rwMutex.Unlock() // Sblocca per scrittura
}

func main() {
	go writeData("Ciao")
	time.Sleep(100 * time.Millisecond) // Dà tempo alla scrittura

	for i := 0; i < 5; i++ {
		go readData() // Sono consentite molte letture contemporaneamente
	}

	time.Sleep(time.Second) // Dà tempo alle goroutine di finire
	go writeData("Mondo")
	time.Sleep(100 * time.Millisecond)
	go readData()

	time.Sleep(time.Second)
}