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 + "&a=0&b=1&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 }
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) } ...
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!