Gelagat Pembolehubah Dikongsi Goroutine dalam Go
Soalan:
Semasa meneroka ciri konkurensi Go, pembangun mengalami gelagat yang tidak dijangka apabila berkongsi pembolehubah antara goroutine. Dengan adanya pengubahsuaian kod tertentu, output sangat berbeza.
Dalam coretan kod di bawah, setiap goroutine mencetak nilai x yang sepadan dengan betul:
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) x := i go func() { defer wg.Done() fmt.Println(x) }() } wg.Wait() fmt.Println("Done") }
Walau bagaimanapun, pengubahsuaian sedikit pada kod menghasilkan hasil yang seragam untuk semua goroutine:
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() fmt.Println(i) }() } wg.Wait() fmt.Println("Done") }
Jawapan:
Dalam coretan pertama, setiap goroutine mempunyai contoh baharu bagi pembolehubah x. Ini kerana x := i mencipta pembolehubah baharu dengan setiap lelaran gelung.
Untuk menunjukkan ini, kita boleh mencetak alamat memori x di dalam setiap goroutine:
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) x := i go func() { defer wg.Done() fmt.Println(&x) }() } wg.Wait() fmt.Println("Done") }
Menjalankan kod ini akan menunjukkan alamat memori yang berbeza untuk setiap goroutine.
Dalam coretan kedua, pembolehubah i dirujuk terus dalam fungsi tanpa nama yang diluluskan untuk pergi func(). Ini bermakna semua goroutine berkongsi nilai i yang sama, yang menyumbang kepada output seragam.
Atas ialah kandungan terperinci Mengapa Goroutine Mencetak Nilai Berbeza Apabila Berkongsi Pembolehubah dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!