Sobes.tech
Middle

Τι τύπους mutex παρέχει η τυπική βιβλιοθήκη του Go;

sobes.tech AI

Απάντηση από AI

Η προεπιλεγμένη βιβλιοθήκη του Go παρέχει δύο βασικούς τύπους mutex στο πακέτο sync:

  • sync.Mutex: Βασικό mutex που διασφαλίζει την αμοιβαία αποκλεισμό. Μπορεί να βρίσκεται σε δύο καταστάσεις: κλειδωμένο ή ξεκλείδωτο. Μόνο μια goroutine μπορεί να διατηρεί το κλείδωμα τη φορά.
  • sync.RWMutex: Mutex για ανάγνωση/εγγραφή. Επιτρέπει σε πολλές goroutines να διαβάζουν δεδομένα ταυτόχρονα (RLock), αλλά μόνο σε μία να γράφει (Lock). Η εγγραφή μπλοκάρει όλες τις λειτουργίες (ανάγνωση και εγγραφή).

Βασικές μέθοδοι του sync.Mutex:

Μέθοδος Περιγραφή
Lock() Κλειδώνει το mutex. Αν ήδη είναι κλειδωμένο, η καλούσα goroutine μπλοκάρεται μέχρι να απελευθερωθεί.
Unlock() Ξεκλειδώνει το mutex. Προκαλεί panic αν το mutex δεν ήταν κλειδωμένο από την καλούσα goroutine.

Βασικές μέθοδοι του sync.RWMutex:

Μέθοδος Περιγραφή
Lock() Κλειδώνει το mutex για εγγραφή. Μπλοκάρει όλες τις λειτουργίες ανάγνωσης και εγγραφής.
Unlock() Ξεκλειδώνει το mutex για εγγραφή. Προκαλεί panic αν το mutex δεν ήταν κλειδωμένο για εγγραφή.
RLock() Κλειδώνει το mutex για ανάγνωση. Δεν μπλοκάρει άλλες λειτουργίες ανάγνωσης. Μπλοκάρεται αν υπάρχει κλείδωμα εγγραφής.
RUnlock() Ξεκλειδώνει το mutex για ανάγνωση. Προκαλεί panic αν το mutex δεν ήταν κλειδωμένο για ανάγνωση.
RLocker() Επιστρέφει ένα Locker που χρησιμοποιεί RLock και RUnlock.

Παράδειγμα χρήσης του sync.Mutex:

package main

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

var counter int
var mutex sync.Mutex

func increment() {
	mutex.Lock() // Κλειδώνει το mutex
	counter++
	fmt.Printf("Counter: %d\n", counter)
	mutex.Unlock() // Ξεκλειδώνει το mutex
}

func main() {
	for i := 0; i < 10; i++ {
		go increment()
	}
	time.Sleep(time.Second) // Περιμένει να τελειώσουν οι goroutines
}

Παράδειγμα χρήσης του sync.RWMutex:

package main

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

var data string
var rwMutex sync.RWMutex

func readData() {
	rwMutex.RLock() // Κλειδώνει για ανάγνωση
	fmt.Printf("Ανάγνωση δεδομένων: %s\n", data)
	rwMutex.RUnlock() // Ξεκλειδώνει για ανάγνωση
}

func writeData(newData string) {
	rwMutex.Lock() // Κλειδώνει για εγγραφή
	data = newData
	fmt.Printf("Εγγραφή δεδομένων: %s\n", data)
	rwMutex.Unlock() // Ξεκλειδώνει για εγγραφή
}

func main() {
	go writeData("Γειά")
	time.Sleep(100 * time.Millisecond) // Περιμένει για την εγγραφή

	for i := 0; i < 5; i++ {
		go readData() // Επιτρέπονται πολλαπλές ταυτόχρονες αναγνώσεις
	}

	time.Sleep(time.Second) // Περιμένει να τελειώσουν οι goroutines
	go writeData("Κόσμε")
	time.Sleep(100 * time.Millisecond)
	go readData()

	time.Sleep(time.Second) // Περιμένει
}