Als Teil des offiziellen Go-Pakets enthält das Sync-Paket die folgende Aussage:
Das Sync-Paket stellt grundlegende Synchronisierungsprimitive bereit, wie z. B. Mutex-Sperren. Mit Ausnahme der Typen Once und WaitGroup sind die meisten anderen Typen für die zugrunde liegende Funktionsbibliothek vorgesehen. Eine Synchronisierung auf höherer Ebene lässt sich besser über Kanäle und Kommunikation erreichen.
In den meisten Beispielen, die Sie finden können, um den gleichzeitigen Zugriff zu ermöglichen, verwenden viele Mutexe, um das Problem zu lösen. Es gibt jedoch nur wenige Beispiele, die uns zeigen, wie Kanäle zur Bereitstellung von Synchronisationsmechanismen verwendet werden können. Lassen Sie uns dies in diesem Artikel besprechen.
Damit die Mutex-Sperre funktioniert, muss sie beim Zugriff auf die gemeinsam genutzte Variable gesperrt und nach Abschluss des Vorgangs entsperrt werden. Derselbe Mutex darf nicht mehrmals gesperrt werden, um Race Conditions zu vermeiden.
Wenn kein Empfänger vorhanden ist, blockiert der Absender. Wenn kein Absender vorhanden ist, blockiert der Empfänger. Aufgrund dieser Eigenschaft können wir ungepufferte Kanäle nicht als Sperren verwenden.
Mal sehen, ob der Pufferkanal als Mutex-Sperre verwendet werden kann.
Ein Kanal mit einer Puffergröße von 1 hat die folgenden Eigenschaften: Wenn der Puffer voll ist, wird das Senden blockiert, wenn der Puffer leer ist , der Versand wird blockiert. Entsperren.
Offensichtlich sind die Sperreigenschaften dieses Kanals wünschenswert Funktion durch Code.
Wir gehen davon aus, dass es eine Spalte mit Namen gibt, die in die Datei geschrieben werden müssen, und jeder Name muss 1000 Mal hintereinander geschrieben werden Es ist keine Überschneidung verschiedener Namen zulässig.
package main import ( "errors" "fmt" "os" "sync" ) func main() { file, err := os.Create("record.txt") defer func() { if err := recover(); err != nil { fmt.Printf("Error encounter: %w", err) } file.Close() }() if err != nil { panic(errors.New("Cannot create/open file")) } ss := []string{ //string slice literals "James", "Avery", "Peter", "John", "Beau", } chanLock := make(chan int, 1) //1 var wg sync.WaitGroup for _, str := range ss { //2 wg.Add(1) //amended thanks to response from Wang //Sheng go func(aString string) { chanLock <- 1 //3 for i := 0; i < 1000; i++ { file.WriteString(aString + "\n") } <-chanLock //4 wg.Done() //5 }(str) //pass by value } wg.Wait() }
Im obigen Code //1 erstellen wir einen Kanal mit einem Puffer von 1. //2 Wir haben so viele Goroutinen erstellt wie Namen. //3 entspricht dem Sperren, //4 entspricht dem Entsperren, sodass mehrere Goroutinen synchron Namen in die Datei record.txt schreiben können, die Datei jedoch jeweils nur von einer Goroutine bearbeitet wird.
Es ist zu beachten, dass wir WaitGroup verwenden, um sicherzustellen, dass die Haupt-Goroutine nicht beendet wird, bevor die untergeordnete Goroutine die Aufgabe abgeschlossen hat.
Ich hoffe, dieser Artikel ist hilfreich für Sie, viel Spaß beim Programmieren!
Das obige ist der detaillierte Inhalt vonGelernt! Verwenden Sie gepufferte Kanäle als Mutexe. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!