Heim >Backend-Entwicklung >Golang >Warum führt die Verwendung von sync.WaitGroup mit externen Funktionen zu einem Deadlock?

Warum führt die Verwendung von sync.WaitGroup mit externen Funktionen zu einem Deadlock?

DDD
DDDOriginal
2024-11-06 19:43:02718Durchsuche

Why Does Using sync.WaitGroup with External Functions Lead to Deadlock?

Sync.WaitGroup mit externen Funktionen verwenden

In einem Programm können Probleme auftreten, wenn sync.WaitGroup mit Funktionen verwendet wird, die außerhalb der Hauptfunktion definiert sind. Lassen Sie uns diese Situation untersuchen.

Problem:

Bedenken Sie den folgenden Code:

<code class="go">package main

import (
    "fmt"
    "sync"
)

func main() {
    ch := make(chan int)
    var wg sync.WaitGroup
    wg.Add(2)
    go Print(ch, wg) //
    go func(){

        for i := 1; i <= 11; i++ {
            ch <- i
        }

        close(ch)
        defer wg.Done()
    }()

    wg.Wait() //deadlock here
}

// Print prints all numbers sent on the channel.
// The function returns when the channel is closed.
func Print(ch <-chan int, wg sync.WaitGroup) {
    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
    defer wg.Done()
}</code>

Hier streben Sie an, dass das Programm Zahlen drucken soll 1 bis 11, aber gelegentlich werden nur 1 bis 10 gedruckt.

Fehler Analyse:

Sie übergeben eine Kopie von sync.WaitGroup an die Print-Funktion, was bedeutet, dass die Done()-Methode für die sync.WaitGroup, auf die Sie warten, nicht aufgerufen wird Hauptfunktion.

Lösung:

Um dieses Problem zu beheben, aktualisieren Sie den Code als folgt:

<code class="go">package main

import (
    "fmt"
    "sync"
)

func main() {
    ch := make(chan int)

    var wg sync.WaitGroup
    wg.Add(2)

    go Print(ch, &wg)

    go func() {
        for i := 1; i <= 11; i++ {
            ch <- i
        }
        close(ch)
        defer wg.Done()
    }()

    wg.Wait() //deadlock here
}

func Print(ch <-chan int, wg *sync.WaitGroup) {
    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
    defer wg.Done()
}</code>

Dadurch wird sichergestellt, dass die Print-Funktion die Done()-Methode auf derselben sync.WaitGroup aufruft, auf die Sie in der Hauptfunktion warten.

Alternativ können Sie eine Umstrukturierung durchführen Ihr Code, um die Abhängigkeit von sync.WaitGroup in der Druckfunktion zu entfernen:

<code class="go">package main

import (
    "fmt"
)

func main() {
    ch := make(chan int)

    go func() {
        for i := 1; i <= 11; i++ {
            ch <- i
        }
        close(ch)
    }()

    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
}</code>

Das obige ist der detaillierte Inhalt vonWarum führt die Verwendung von sync.WaitGroup mit externen Funktionen zu einem Deadlock?. 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