Rumah > pembangunan bahagian belakang > Golang > Mengapa Gabungan `sync.WaitGroup` dan Saluran Membawa kepada Kebuntuan dalam Pergi?

Mengapa Gabungan `sync.WaitGroup` dan Saluran Membawa kepada Kebuntuan dalam Pergi?

Susan Sarandon
Lepaskan: 2024-10-30 17:43:02
asal
1018 orang telah melayarinya

Why Does a `sync.WaitGroup` and Channel Combination Lead to a Deadlock in Go?

Memahami Kebuntuan apabila menggunakan penyegerakan.WaitGroup dan Saluran dalam Go

Pembangun sering menghadapi masalah dengan aplikasi Go mereka yang tidak pernah keluar apabila menggunakan penyegerakan.WaitGroup dan saluran. Artikel ini meneroka sebab di sebalik kebuntuan tersebut dan menawarkan penyelesaian menggunakan WaitGroup.

Pertimbangkan contoh kod yang disediakan:

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "os"
    "sync"
)

var symbols = []string{
    "ASSA-B.ST",
    "ELUX-B.ST",
    "HM-B.ST",
}

func main() {

    fmt.Println("fetching quotes...")

    fetchedSymbols := make(chan string)
    var wg sync.WaitGroup
    wg.Add(len(symbols))

    for _, symbol := range symbols {
        go fetchSymbol(symbol, &wg, fetchedSymbols)
    }

    for response := range fetchedSymbols {
        fmt.Println("fetched " + response)
    }

    wg.Wait()

    fmt.Println("done")

}

func fetchSymbol(symbol string, wg *sync.WaitGroup, c chan<- string) {
    defer wg.Done()
    resp, err := http.Get("http://ichart.yahoo.com/table.csv?s=" + symbol + "&amp;a=0&amp;b=1&amp;c=2000")
    defer resp.Body.Close()

    if err != nil {
        log.Fatal(err)
    }

    out, err := os.Create("./stock-quotes/" + symbol + ".csv")
    defer out.Close()

    if err != nil {
        log.Fatal(err)
    }

    io.Copy(out, resp.Body)
    c <- symbol
}
Salin selepas log masuk

Dalam kod ini, gelung julat ke atas fetchedSymbols akan menyekat kod utama berfungsi selama-lamanya. kenapa? Kerana saluran fetchedSymbols tidak pernah ditutup. Untuk menyelesaikan kebuntuan ini, WaitGroup boleh digunakan untuk memberi isyarat bila hendak menutup saluran:

...
go func() {
    wg.Wait()
    close(fetchedSymbols)
}()

for response := range fetchedSymbols {
    fmt.Println("fetched " + response)
}

...
Salin selepas log masuk

Oleh kerana WaitGroup sudah menjejaki apabila semua goroutine telah selesai, ia boleh dimanfaatkan untuk mencetuskan penutupan saluran fetchedSymbols , memastikan gelung julat ditamatkan dengan anggun.

Atas ialah kandungan terperinci Mengapa Gabungan `sync.WaitGroup` dan Saluran Membawa kepada Kebuntuan dalam Pergi?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan