Parallelität in Go: Eine Einführung
Go ist eine Programmiersprache, die so konzipiert ist, dass sie für die gleichzeitige Programmierung einfach zu verwenden ist. Eine der wichtigsten Möglichkeiten, wie Go gleichzeitiges Programmieren ermöglicht, sind Goroutinen.
Eine Goroutine ist ein leichtgewichtiger Ausführungsthread, der von der Go-Laufzeit verwaltet wird. Goroutinen sind sehr billig zu erstellen und können erstellt werden, indem einfach eine Funktion mit dem goSchlüsselwort davor aufgerufen wird. Zum Beispiel:
go foo()
Go bietet auch eine Reihe von eingebauten Mechanismen für die Kommunikation zwischen Goroutinen, wie z. B. Kanäle, die verwendet werden können, um Daten zwischen Goroutinen zu übertragen.
Hier ist ein einfaches Beispiel, das die Verwendung von Goroutinen und Kanälen demonstriert:
package main
import (
"fmt"
"time"
)
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("worker", id, "processing job", j)
time.Sleep(time.Second)
results <- j * 2
}
}
func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
for a := 1; a <= 5; a++ {
<-results
}
}
Die Hauptfunktion erstellt zwei Kanäle jobsund resultsund startet drei Goroutinen, die jeweils die Worker-Funktion ausführen. Die Hauptfunktion sendet dann fünf Aufgaben an den jobsKanal und schließt ihn, wenn sie fertig ist.
Die Worker-Goroutinen empfangen Aufgaben vom jobsKanal, führen einige Arbeiten an ihnen durch (in diesem Fall schlafen sie nur eine Sekunde lang und multiplizieren die Aufgabe mit zwei) und senden die Ergebnisse an den resultsKanal. Die Hauptfunktion erhält die Ergebnisse vom resultsKanal und macht nichts damit.
Dieses Beispiel zeigt, wie mehrere Goroutinen gleichzeitig an einer Reihe von Aufgaben arbeiten können, wobei die Hauptfunktion die Arbeit koordiniert, indem sie Aufgaben an den jobsKanal sendet und Ergebnisse vom resultsKanal empfängt.
In dem von mir bereitgestellten Beispiel werden die Jobs- und Ergebniskanäle beide mit einer Puffergröße von 100 erstellt. Dies bedeutet, dass sie bis zu 100 Werte enthalten können, bevor sie zu blockieren beginnen.
Es gibt zwei Hauptgründe, warum wir uns in diesem Beispiel für die Verwendung gepufferter Kanäle entscheiden könnten:
1. Leistung: Die Verwendung eines gepufferten Kanals kann die Leistung eines nebenläufigen Programms verbessern, indem es Goroutinen ermöglicht, Werte zu senden und zu empfangen, ohne darauf zu warten, dass die andere Seite bereit ist. Dies kann besonders nützlich sein, wenn die Rate, mit der Werte gesendet und empfangen werden, nicht gut aufeinander abgestimmt ist, da es dem Programm ermöglicht, auch dann weiter Fortschritte zu machen, wenn eine Seite langsamer als die andere ist.
2. Einfachheit: In diesem speziellen Beispiel können wir durch die Verwendung gepufferter Kanäle vermeiden, dass wir das Herunterfahren der Worker-Goroutinen explizit koordinieren müssen. Da der Jobs-Kanal über einen Puffer verfügt, können die Worker-Goroutinen mit der Verarbeitung von Aufgaben fortfahren, bis der Puffer voll ist. An diesem Punkt blockieren sie natürlich, wenn sie versuchen, weitere Ergebnisse zu senden. Auf diese Weise können wir einfach den Jobs-Kanal schließen und dann alle Ergebnisse aus dem Ergebniskanal erhalten, ohne uns Gedanken über das Herunterfahren der Worker-Goroutinen auf komplexere Weise machen zu müssen.
Natürlich gibt es auch potenzielle Nachteile bei der Verwendung gepufferter Kanäle. Beispielsweise kann die Verwendung einer größeren Puffergröße die Speichernutzung erhöhen, und wenn der Puffer nicht effizient verwendet wird, kann dies auch die Latenz des Programms erhöhen. Es ist wichtig, die Kompromisse sorgfältig abzuwägen, wenn entschieden wird, ob und wie gepufferte Kanäle in einem bestimmten Programm verwendet werden sollen.
Nebenläufige Programmierung in Go ist ein leistungsstarkes und benutzerfreundliches Tool zum Erstellen effizienter, skalierbarer Programme. Es eignet sich besonders gut für Aufgaben, die in kleinere, unabhängige Arbeitseinheiten unterteilt werden können, z. B. Aufgaben, die mehrere Netzwerkanforderungen oder CPU-intensive Berechnungen beinhalten.
Zusammenfassend lässt sich sagen, dass die Unterstützung von Go für die gleichzeitige Programmierung ein Schlüsselmerkmal der Sprache ist, das sie gut geeignet macht, um effiziente, skalierbare Programme zu erstellen. Goroutinen und Kanäle sind leistungsstarke Tools, mit denen Entwickler auf einfache Weise gleichzeitigen Code schreiben können, der mehrere CPU-Kerne und andere Ressourcen nutzen kann.
Nebenläufiges Programmieren kann eine Herausforderung sein, aber der einfache und unkomplizierte Ansatz von Go macht es Entwicklern leichter, korrekten, effizienten nebenläufigen Code zu schreiben. Mit ein wenig Übung und den richtigen Tools ist es möglich, leistungsstarke nebenläufige Programme in Go zu erstellen, die die verfügbare Hardware voll ausnutzen können.
Danke fürs Lesen

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































