Bei der gleichzeitigen Programmierung ist Sperren ein Mechanismus zum Schutz gemeinsam genutzter Ressourcen. In der Go-Sprache sind Sperren eines der wichtigen Werkzeuge zum Erreichen von Parallelität. Es stellt sicher, dass beim gleichzeitigen Zugriff mehrerer Coroutinen auf gemeinsam genutzte Ressourcen nur eine Coroutine diese Ressourcen lesen oder ändern kann. In diesem Artikel wird die Verwendung von Sperren in der Go-Sprache vorgestellt, um den Lesern ein besseres Verständnis der gleichzeitigen Programmierung zu ermöglichen.
Mutual Exclusion Lock ist der am häufigsten verwendete Sperrmechanismus in der Go-Sprache. Dadurch wird sichergestellt, dass nur eine Coroutine gleichzeitig auf den kritischen Abschnitt zugreifen kann. Laienhaft ausgedrückt stellt eine Mutex-Sperre sicher, dass nur eine Coroutine gleichzeitig darauf zugreifen kann, indem gemeinsam genutzte Ressourcen in einen sperrenkritischen Abschnitt eingeschlossen werden.
Die Verwendung von Mutex-Sperren in der Go-Sprache ist sehr einfach. Wir können den Mutex-Typ im Synchronisierungspaket verwenden, um eine Mutex-Sperre zu erstellen:
import "sync" var mutex = &sync.Mutex{}
Danach können wir an dem Ort, an dem gemeinsam genutzte Ressourcen geschützt werden müssen, den folgenden Code verwenden, um die Sperre zu erhalten:
mutex.Lock() defer mutex.Unlock()
import ( "fmt" "sync" ) var count = 0 var mutex = &sync.Mutex{} func increment(wg *sync.WaitGroup) { mutex.Lock() defer mutex.Unlock() count++ wg.Done() } func main() { var wg sync.WaitGroup for i := 0; i < 1000; i++ { wg.Add(1) go increment(&wg) } wg.Wait() fmt.Println("Count:", count) }
import "sync" var rwlock = &sync.RWMutex{}
import ( "fmt" "sync" ) var count = 0 var rwlock = &sync.RWMutex{} func increment(wg *sync.WaitGroup) { rwlock.Lock() defer rwlock.Unlock() count++ wg.Done() } func read(wg *sync.WaitGroup) { rwlock.RLock() defer rwlock.RUnlock() fmt.Println("Count:", count) wg.Done() } func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go increment(&wg) } wg.Wait() for i := 0; i < 5; i++ { wg.Add(1) go read(&wg) } wg.Wait() }
In diesem Beispiel haben wir gleichzeitig 10 Coroutinen geöffnet, um Daten in den Zähler zu schreiben, und 5 Coroutinen, um die Zählerdaten zu lesen. Durch die Verwendung von Lese-/Schreibsperren können Programme gemeinsam genutzte Ressourcen auf effiziente Weise lesen und gleichzeitig die Atomizität von Schreibvorgängen sicherstellen.
AtomoperationenDie Go-Sprache verfügt über mehrere integrierte atomare Operationsfunktionen. Sie können sich auf die offizielle Dokumentation beziehen. Hier sind zwei häufig verwendete atomare Operationsfunktionen: atomic.Add und atomic.Load.
atomic.Add: Führt eine atomare Additionsoperation für eine Ganzzahl durch.import ( "fmt" "sync/atomic" "time" ) var count int32 = 0 func increment(wg *sync.WaitGroup) { defer wg.Done() atomic.AddInt32(&count, 1) } func printCount() { fmt.Println("Count: ", atomic.LoadInt32(&count)) } func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go increment(&wg) } wg.Wait() printCount() time.Sleep(time.Second) for i := 0; i < 3; i++ { wg.Add(1) go increment(&wg) } wg.Wait() printCount() }
In diesem Beispiel verwenden wir die Funktion atomic.Add, um atomare Additionsoperationen am Zähler und am atomaren durchzuführen .Funktion atomar laden. Den Zählerwert manuell lesen. Durch die Verwendung atomarer Operationen können wir den Overhead von Sperren vermeiden und eine effizientere gleichzeitige Programmierung erreichen.
ZusammenfassungDas obige ist der detaillierte Inhalt vonWie verwende ich Sperren in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!