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

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

Susan Sarandon
Susan Sarandonasal
2024-10-26 13:28:02924semak imbas

 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>

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!

Kenyataan:
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