Rumah > pembangunan bahagian belakang > Golang > Di Mana Anda Harus Meletakkan `wg.Add()` dalam Program Concurrent Go?

Di Mana Anda Harus Meletakkan `wg.Add()` dalam Program Concurrent Go?

Susan Sarandon
Lepaskan: 2024-10-26 13:28:02
asal
994 orang telah melayarinya

 Where Should You Place `wg.Add()` in Concurrent Go Programs?

Memahami Peletakan wg.Add()

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>
Salin selepas log masuk

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>
Salin selepas log masuk

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!

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