Heim >Backend-Entwicklung >Golang >Wo sollten Sie „wg.Add()' in gleichzeitigen Go-Programmen platzieren?

Wo sollten Sie „wg.Add()' in gleichzeitigen Go-Programmen platzieren?

Susan Sarandon
Susan SarandonOriginal
2024-10-26 13:28:02997Durchsuche

 Where Should You Place `wg.Add()` in Concurrent Go Programs?

Grundlegendes zur Platzierung von wg.Add()

In gleichzeitigen Go-Programmen dient der Typ sync.WaitGroup als Synchronisierungsgrundelement, um die Erledigung von Aufgaben zu koordinieren. Wenn Sie mit einer WaitGroup arbeiten, ist es entscheidend, wo Sie den wg.Add()-Aufruf platzieren, um ein ordnungsgemäßes Warteverhalten sicherzustellen.

Beachten Sie den folgenden Code:

<code class="go">var wg sync.WaitGroup
var v int32 = 0

for i := 0; i < 100; i++ {
    go func() {
        wg.Add(1) // wrong place
        atomic.AddInt32(&v, 1)
        wg.Done()
    }()
}
wg.Wait()
fmt.Println(v)</code>

Dieser Code soll a parallelisieren Reihe von Aufgaben ausführen und gleichzeitig eine gemeinsam genutzte Variable v erhöhen. Allerdings führt die Ausgabe oft zu Werten unter 100. Das Problem liegt in der Platzierung von wg.Add(1) innerhalb der anonymen Goroutine.

Durch die Platzierung von wg.Add(1) innerhalb der Goroutine, der Haupt- Goroutine kann die Ausführung fortsetzen, bevor wg.Done() aufgerufen wird. Dies kann auftreten, weil das Parallelitätsmodell die gleichzeitige Ausführung des Aufrufs wg.Add(1) und des Aufrufs wg.Done() zulässt, was möglicherweise zu einer vorzeitigen Beendigung des Wartens in der Haupt-Goroutine führt.

Um dieses Problem zu beheben Problem, der wg.Add(1)-Aufruf sollte außerhalb der Goroutine verschoben werden, wie unten gezeigt:

<code class="go">var wg sync.WaitGroup
var v int32 = 0

for i := 0; i < 100; i++ {
    wg.Add(1)
    go func() {
        atomic.AddInt32(&v, 1)
        wg.Done()
    }()
}
wg.Wait()
fmt.Println(v)</code>

Durch das Verschieben von wg.Add(1) außerhalb der Goroutine stellen wir sicher, dass die Haupt-Goroutine blockiert beim Aufruf von wg.Wait(), bis alle Goroutinen abgeschlossen sind und wg.Done() aufrufen. Dies garantiert, dass der Endwert von v korrekt ist.

Als allgemeine Praxis wird empfohlen, immer wg.Add() aufzurufen, bevor eine Goroutine gestartet wird, die wg.Done() aufruft. Dies gewährleistet ein ordnungsgemäßes Warteverhalten und eliminiert eventuell auftretende Race Conditions.

Das obige ist der detaillierte Inhalt vonWo sollten Sie „wg.Add()' in gleichzeitigen Go-Programmen platzieren?. 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