Heim > Artikel > Backend-Entwicklung > Der beste Weg, gleichzeitige und asynchrone Programmierung mit der Go-Sprache zu implementieren
Mit der Verbesserung der Leistung der Computerhardware müssen immer mehr Anwendungen eine große Anzahl gleichzeitiger und asynchroner Aufgaben bewältigen. Dies wirft die Frage auf: Wie können diese Aufgaben effizient erledigt und die Qualität des Codes sichergestellt werden? Die Go-Sprache verfügt über die inhärente Fähigkeit, gleichzeitige und asynchrone Programmierung zu unterstützen. In diesem Artikel wird die beste Möglichkeit vorgestellt, gleichzeitige und asynchrone Programmierung mithilfe der Go-Sprache zu implementieren.
1. Verstehen Sie die Parallelität und das asynchrone Programmiermodell der Go-Sprache.
Die Parallelität und das asynchrone Programmiermodell der Go-Sprache werden basierend auf Goroutine und Kanal implementiert. Goroutine ist ein leichter Thread, der mehrere Aufgaben gleichzeitig in einem Programm ausführen kann. Kanal ist ein Kommunikationskanal zwischen Goroutinen, der die Datenübertragung zwischen verschiedenen Goroutinen realisieren kann.
In der Go-Sprache kann eine neue Goroutine mit dem Schlüsselwort go gestartet werden. Wie unten gezeigt:
go func() { // do something }()
Im obigen Code stellt func() den auszuführenden Funktionscode dar. Wenn Sie diese Funktion mit dem Schlüsselwort go starten, wird sie in einer neuen Goroutine ausgeführt.
In der Go-Sprache wird das CSP-Modell (Communicating Sequential Processes) übernommen, was bedeutet, dass Parallelität und Zusammenarbeit über Kanäle erfolgen. Ein Kanal hat zwei Endpunkte: Senden und Empfangen. Die Kommunikation zwischen Goroutinen kann durch Senden und Empfangen von Kanälen erreicht werden.
2. So erstellen und verwenden Sie einen Kanal
Erstellen Sie in der Go-Sprache einen Kanal über die Make-Funktion. So erstellen Sie einen Kanal vom Typ String:
ch := make(chan string)
Verwenden Sie das <-Symbol, um Daten an den Kanal zu senden:
ch <- "Hello world"
Verwenden Sie das <-Symbol, um Daten zu empfangen vom Kanal:
msg := <-ch
Hinweis: Wenn keine Daten zum Empfangen vorhanden sind, blockiert das Programm den Empfangsvorgang. Wenn der Kanal voll ist, wird der Sendevorgang ebenfalls blockiert.
Es gibt auch eine Schlüsselwortauswahl in der Go-Sprache, mit der die Ausführung von Goroutine ausgewählt werden kann. Select kann mehrere Fälle enthalten. Jeder Fall ist ein Empfangs- oder Sendevorgang eines Kanals. Wenn „select“ ausgeführt wird, wird zufällig ein verfügbarer Fall zur Ausführung ausgewählt. Wenn kein Fall verfügbar ist, wird er blockiert.
Hier ist ein Beispiel:
ch1 := make(chan int) ch2 := make(chan int) go func() { for i := 0; i < 10; i++ { ch1 <- i } }() go func() { for i := 0; i < 10; i++ { ch2 <- i } }() for i := 0; i < 20; i++ { select { case v := <-ch1: fmt.Println("ch1:", v) case v := <-ch2: fmt.Println("ch2:", v) } }
Im obigen Beispiel haben wir zwei Goroutinen erstellt, eine zum Senden von Daten an Kanal 1 und die andere zum Senden von Daten an Kanal 2. Verwenden Sie dann die Select-Anweisung in der Haupt-Goroutine, um die Daten von CH1 und CH2 zu überwachen. Wenn Daten verfügbar sind, wird die entsprechende Case-Anweisung ausgeführt.
3. Verwenden Sie WaitGroup, um die Ausführung von Goroutine zu steuern
Normalerweise müssen wir warten, bis die gesamte Goroutine-Ausführung abgeschlossen ist, bevor wir andere Vorgänge ausführen. Sie können WaitGroup im Synchronisierungspaket verwenden, um diese Anforderung zu erfüllen. WaitGroup kann verwendet werden, um auf den Abschluss einer Gruppe von Goroutinen zu warten.
Das Folgende ist ein Beispiel:
var wg sync.WaitGroup func main() { for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() // do something }() } wg.Wait() // All goroutines are done }
Im obigen Beispiel haben wir 10 Goroutinen erstellt und der Aufruf der Add-Methode in WaitGroup zeigt an, dass 10 Goroutinen ausgeführt werden. Verwenden Sie dann defer stmt.Done() in jeder Goroutine, um WaitGroup mitzuteilen, dass die Goroutine abgeschlossen ist. Schließlich wird die Wait-Methode in der Haupt-Goroutine aufgerufen, um darauf zu warten, dass alle Goroutinen die Ausführung abschließen.
4. Verwenden Sie sync.Mutex, um die Datensicherheit zu gewährleisten.
Wenn in der Go-Sprache von mehreren Goroutinen gleichzeitig auf eine Variable zugegriffen wird, müssen Sie a verwenden Sperre, um die Datensicherheit zu gewährleisten. Sperren können mit Mutex aus dem Sync-Paket implementiert werden.
Hier ist ein Beispiel:
var mu sync.Mutex var count int func inc() { mu.Lock() defer mu.Unlock() count++ } func main() { for i := 0; i < 10; i++ { go inc() } time.Sleep(time.Second) fmt.Println("count:", count) }
Im obigen Beispiel haben wir ein .Mutex-Objekt erstellt, um sicherzustellen, dass der Zugriff auf count threadsicher ist. In der Funktion „inc“ erwerben wir zunächst die Sperre und geben sie dann in „defer“ frei. In der Hauptfunktion starten wir 10 Inc-Goroutinen, um auf count zuzugreifen.
5. Verwenden Sie das Kontextpaket, um Zeitüberschreitungen und Abbrüche zu verarbeiten.
In der Go-Sprache können wir das Kontextpaket verwenden, um Zeitüberschreitungen und Abbrüche zu behandeln, um Goroutine-Lecks und Ressourcenverschwendung zu vermeiden . Der Kontext kann Fristen festlegen und Signale abbrechen. Alle Goroutinen werden abgebrochen, wenn das Signal ausgelöst wird.
Das Folgende ist ein Beispiel:
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() ch := make(chan int) go func() { time.Sleep(time.Second * 5) ch <- 1 }() select { case <-ch: fmt.Println("received") case <-ctx.Done(): fmt.Println("timeout or cancelled") }
Im obigen Beispiel verwenden wir die context.WithTimeout-Funktion, um ein Context-Objekt mit einem Timeout von 3 Sekunden zu erstellen und ein zu starten Goroutine soll 5 Sekunden warten. Wenn in der Select-Anweisung die Goroutine innerhalb von 3 Sekunden abgeschlossen ist, geben Sie „received“ aus, andernfalls geben Sie „timeout or cancelled“ aus.
6. Zusammenfassung
Gleichzeitige und asynchrone Programmierung können mit der Go-Sprache einfach implementiert werden. Durch die Verwendung von Goroutinen und Kanälen können wir effiziente Parallelitätsmodelle erstellen. Gleichzeitig kann die Verwendung von WaitGroup, Mutex und Context unser Programm sicherer und robuster machen.
Natürlich können hohe Parallelität und asynchrone Programmierung bei unsachgemäßer Verwendung auch einige Probleme verursachen, z. B. Rennbedingungen, Deadlocks, Hunger und andere Probleme. Achten Sie daher bei der gleichzeitigen und asynchronen Programmierung unbedingt auf die Qualität und Korrektheit des Codes.
Das obige ist der detaillierte Inhalt vonDer beste Weg, gleichzeitige und asynchrone Programmierung mit der Go-Sprache zu implementieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!