Sobes.tech
Middle+

Πώς να προστατευτείτε από σφάλματα κατά την ανταγωνιστική εγγραφή σε ένα χάρτη;

sobes.tech AI

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

Για την προστασία από σφάλματα κατά την ανταγωνιστική εγγραφή σε map στο Golang, που δεν είναι από προεπιλογή ασφαλείς για νήματα, χρησιμοποιούνται οι ακόλουθοι μηχανισμοί:

  • sync.Mutex: Κλείδωμα του map πριν την εγγραφή και ξεκλείδωμα μετά.

    import "sync"
    
    type SafeMap struct {
        mu sync.Mutex
        data map[string]int
    }
    
    func NewSafeMap() *SafeMap {
        return &SafeMap{
            data: make(map[string]int),
        }
    }
    
    func (sm *SafeMap) Set(key string, value int) {
        sm.mu.Lock()
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMap) Get(key string) (int, bool) {
        sm.mu.Lock()
        defer sm.mu.Unlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.RWMutex: Επιτρέπει ταυτόχρονη ανάγνωση από πολλαπλά goroutines, αλλά μπλοκάρει την εγγραφή κατά την ταυτόχρονη ανάγνωση ή εγγραφή.

    import "sync"
    
    type SafeMapRWMutex struct {
        mu sync.RWMutex
        data map[string]int
    }
    
    func NewSafeMapRWMutex() *SafeMapRWMutex {
        return &SafeMapRWMutex{
            data: make(map[string]int),
        }
    }
    
    func (sm *SafeMapRWMutex) Set(key string, value int) {
        sm.mu.Lock() // Write lock
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMapRWMutex) Get(key string) (int, bool) {
        sm.mu.RLock() // Read lock
        defer sm.mu.RUnlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.Map: Εξειδικευμένος τύπος ασφαλής για νήματα, βελτιστοποιημένος για σενάρια όπου το σύνολο των κλειδιών είναι σχετικά σταθερό, και οι εγγραφές είναι σπάνιες, ή όταν πολλαπλά goroutines διαβάζουν και γράφουν για διακριτά σύνολα κλειδιών.

    import "sync"
    
    var safeMap sync.Map // Δήλωση
    
    func UseSyncMap() {
        safeMap.Store("key1", 10) // Εγγραφή
        if val, ok := safeMap.Load("key1"); ok { // Ανάγνωση
            // Χρησιμοποιήστε το val
        }
        safeMap.Delete("key1") // Διαγραφή
    }
    

Σύγκριση προσεγγίσεων:

Μηχανισμός Πλεονεκτήματα Μειονεκτήματα Εφαρμογή
sync.Mutex Απλός στη χρήση Μπλοκάρει όλες τις λειτουργίες κατά την εγγραφή Απλά σενάρια, όπου ο ανταγωνισμός δεν είναι υψηλός ή η ανάγνωση/εγγραφή είναι περίπου ίσες.
sync.RWMutex Επιτρέπει παράλληλη ανάγνωση Πιο πολύπλοκος από το sync.Mutex. Η εγγραφή μπλοκάρει την ανάγνωση και άλλες εγγραφές. Σενάρια με συχνή ανάγνωση και σπάνια εγγραφή.
sync.Map Βελτιστοποιημένος για συγκεκριμένα σενάρια Περιορισμένο API. Μπορεί να είναι πιο αργός από το Mutex, αν η πρόσβαση είναι τυχαία. Σενάρια με σχετικά σταθερά κλειδιά ή διακριτά σύνολα κλειδιών για πρόσβαση από διαφορετικά goroutines.

Η επιλογή συγκεκριμένης προσέγγισης εξαρτάται από το χαρακτήρα της ανταγωνιστικής πρόσβασης στο map. Για γενικές περιπτώσεις, συχνά αρκεί το sync.Mutex ή το sync.RWMutex. Για εξειδικευμένα σενάρια, το sync.Map μπορεί να προσφέρει καλύτερη απόδοση.