Dalam program Go serentak, jenis sync.WaitGroup berfungsi sebagai penyegerakan primitif untuk menyelaraskan penyiapan tugas. Apabila bekerja dengan WaitGroup, tempat anda meletakkan panggilan wg.Add() adalah penting untuk memastikan gelagat menunggu yang betul.
Pertimbangkan kod berikut:
<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>
Kod ini bertujuan untuk menyamakan a siri tugasan dan menambah pembolehubah yang dikongsi v secara serentak. Walau bagaimanapun, output selalunya menghasilkan nilai kurang daripada 100. Isunya terletak pada peletakan wg.Add(1) dalam goroutine tanpa nama.
Dengan meletakkan wg.Add(1) dalam goroutine, yang utama goroutine boleh menyambung semula pelaksanaan sebelum wg.Done() dipanggil. Ini boleh berlaku kerana model konkurensi membenarkan kedua-dua panggilan wg.Add(1) dan wg.Done() untuk melaksanakan secara serentak, yang berpotensi membawa kepada penamatan pramatang menunggu dalam goroutine utama.
Untuk menyelesaikan masalah ini isu, panggilan wg.Add(1) harus dialihkan ke luar goroutine, seperti yang ditunjukkan di bawah:
<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>
Dengan mengalihkan wg.Add(1) di luar goroutine, kami memastikan bahawa goroutine utama akan menyekat pada panggilan wg.Wait() sehingga semua goroutine selesai dan dipanggil wg.Done(). Ini menjamin bahawa nilai akhir v adalah tepat.
Sebagai amalan umum, adalah disyorkan untuk sentiasa memanggil wg.Add() sebelum melancarkan goroutine yang akan memanggil wg.Done(). Ini memastikan tingkah laku menunggu yang betul dan menghapuskan sebarang keadaan perlumbaan yang mungkin timbul.
Atas ialah kandungan terperinci Di Mana Anda Harus Meletakkan `wg.Add()` dalam Program Concurrent Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!