Herzlichen Glückwunsch zum Lernen Go. Als jemand Neuem ist es nett, Nebenläufigkeit zu verstehen und wie es sich von Parallelismus unterscheidet.
Concurrency
Concurrency ist wie ein Taschenspieler mit einer Hand mehrere Kugeln in der Luft jonglieren. Egal wie viele Bälle er jongliert, nur ein Ball berührt seine Hand jeden Moment.
Parallelism
Wenn der Jongleur beginnt mehr Kugeln mit der anderen Hand parallel jongliert haben wir zwei gleichzeitige Prozesse zur gleichen Zeit ausgeführt werden.
Goroutines sind groß, weil sie beide gleichzeitige und Auto-parallel, abhängig von den Rechenkernen zur Verfügung und das GOMAXPROCS
Variable, Set sind.
Die Einhand Juggler
Zurück zur einhändigen, Single-entkernt, gleichzeitig Jongleur. Stellen Sie sich vor, dass er drei Bälle mit den Namen "Hallo", "Welt" und "Mars" jongliert, wobei die Hand die main
Routine ist.
var balls = []string{"hello", "world", "mars"}
func main() {
go say(balls[0])
go say(balls[1])
go say(balls[2])
}
oder besser,
func main() {
for _, ball := range balls {
go say(ball)
}
}
Sobald die drei Kugeln in die Luft nacheinander geworfen, zieht sich die Gaukler einfach seine Hand sofort. Das heißt, die main
Routine endet, bevor der erste geworfene Ball überhaupt auf seiner Hand landen kann. Schade, die Bälle fallen einfach auf den Boden. Schlechte Show.
Um die Bälle zurück in seine Hand zu bekommen, muss der Jongleur dafür sorgen, dass er für sie auf wartet. Das bedeutet, dass seine Hand die Bälle, die er geworfen hat, im Auge behalten und zählen kann, wenn sie landen.
Der einfachste Weg ist sync.WaitGroup zu verwenden:
import (
"fmt"
"time"
"sync"
)
var balls = []string{"hello", "world", "mars"}
var wg sync.WaitGroup
func main() {
for _, ball := range balls {
// One ball thrown
wg.Add(1)
go func(b string) {
// Signals the group that this routine is done.
defer wg.Done()
// each ball hovers for 1 second
time.Sleep(time.Duration(1) * time.Second)
fmt.Println(b)
// wg.Done() is called before goroutine exits
}(ball)
}
// The juggler can do whatever he pleases while the
// balls are hanging in the air.
// This hand will come back to grab the balls after 1s.
wg.Wait()
}
WaitGroup
einfach ist. Wenn eine Goroutine erzeugt wird, fügt man zu einem "Rückstandszähler" mit WaitGroup.Add(1)
hinzu und ruft WaitGroup.Done()
auf, um den Zähler zu verringern. Sobald der Backlog 0 wird, bedeutet das, dass alle goroutines fertig sind und WaitGroup
aufhören sollte zu warten (und die Bälle greifen!).
Während die Verwendung von Kanälen für die Synchronisation in Ordnung ist, wird empfohlen, verfügbare gleichzeitige Tools zu verwenden, insbesondere wenn die Verwendung von Kanälen den Code komplexer und schwer zu verstehen macht.
https://gobyexample.com/goroutines – elithrar