Heim >Backend-Entwicklung >Golang >Wie kann ich sicherstellen, dass alle Goroutinen abgeschlossen werden, wenn ich einen gepufferten Kanal als Semaphor verwende?

Wie kann ich sicherstellen, dass alle Goroutinen abgeschlossen werden, wenn ich einen gepufferten Kanal als Semaphor verwende?

Susan Sarandon
Susan SarandonOriginal
2024-12-02 00:54:13557Durchsuche

How Can I Ensure All Goroutines Finish When Using a Buffered Channel as a Semaphore?

Warten auf leere gepufferte Kanäle mithilfe einer WaitGroup

Bei der gleichzeitigen Programmierung ist es häufig erforderlich, die Anzahl der gleichzeitig ausgeführten Goroutinen zu steuern. Ein gängiger Ansatz besteht darin, einen gepufferten Kanal als Semaphor zu verwenden. Es ist jedoch wichtig, die Einschränkungen dieses Ansatzes zu beachten.

Betrachten Sie das folgende Beispiel:

ints := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
 sem := make(chan struct{}, 2)
for _, i := range ints {
  sem<- struct{}{}
  go func(id int, sem chan struct{}) {
    // do something
    <-sem
  }(i, sem)
}

Dieser Code verwendet einen gepufferten Kanal (sem) der Größe 2, um die Anzahl gleichzeitiger Kanäle zu begrenzen Goroutinen auf 2. Es gibt jedoch ein Problem: Das Programm wird möglicherweise beendet, bevor die letzten paar Goroutinen ihre Aufgaben abgeschlossen haben. Dies liegt daran, dass der gepufferte Kanal jederzeit während der Verarbeitung leer werden kann, selbst während das Programm weitere Goroutinen versendet.

Um darauf zu warten, dass ein gepufferter Kanal leer wird, können wir uns nicht auf den Kanal selbst verlassen. Stattdessen können wir eine sync.WaitGroup verwenden, um die Anzahl ausstehender Goroutinen zu verfolgen:

sem := make(chan struct{}, 2)
var wg sync.WaitGroup
for _, i := range ints {
  wg.Add(1)
  sem<- struct{}{}
  go func(id int) {
    defer wg.Done()
    // do something
    <-sem
  }(i)
}
wg.Wait()

In diesem modifizierten Code verwenden wir wg.Add(1), um die Wartegruppe zu erhöhen, bevor jede Goroutine versendet wird. Die defer wg.Done()-Anweisung dekrementiert dann die Wartegruppe, wenn die Goroutine ihre Aufgabe abschließt. Schließlich blockiert wg.Wait(), bis die Wartegruppe Null erreicht, um sicherzustellen, dass die Ausführung aller Goroutinen abgeschlossen ist. Mit diesem Ansatz können wir warten, bis der Kanal leer ist, und sicherstellen, dass das Programm nicht vorzeitig beendet wird.

Das obige ist der detaillierte Inhalt vonWie kann ich sicherstellen, dass alle Goroutinen abgeschlossen werden, wenn ich einen gepufferten Kanal als Semaphor verwende?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn