Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Adakah Tambah dalam Go Thread-Safe Apabila Digunakan dengan Goroutines?

Adakah Tambah dalam Go Thread-Safe Apabila Digunakan dengan Goroutines?

Linda Hamilton
Linda Hamiltonasal
2024-11-11 07:53:02525semak imbas

Is Append in Go Thread-Safe When Used with Goroutines?

Adakah Append Benar-benar Selamat Benang?

Penyegerakan adalah penting apabila berurusan dengan akses serentak kepada sumber kongsi dalam Go. Amalan biasa ialah menambahkan elemen pada kepingan menggunakan goroutine. Walau bagaimanapun, fungsi append tidak semestinya selamat untuk benang.

Dalam kes yang diterangkan, mencipta goroutin berasingan dalam gelung untuk ditambahkan pada kepingan boleh menyebabkan ketidakkonsistenan data. Ini kerana berbilang goroutin menulis pada kepingan yang sama secara serentak boleh mengakibatkan perlumbaan data.

Untuk menunjukkan perkara ini, pertimbangkan coretan kod berikut:

destSlice := make([]myClass, 0)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        destSlice = append(destSlice, tmpObj)
    }(myObject)
}
wg.Wait()

Menjalankan kod ini dengan pilihan -race akan mendedahkan pelbagai perlumbaan data. Untuk mengelakkan perlumbaan ini, mekanisme penyegerakan seperti mutex mesti digunakan. Berikut ialah coretan kod yang disemak menggunakan mutex:

var (
    mu        = &sync.Mutex{}
    destSlice = make([]myClass, 0)
)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        mu.Lock()
        destSlice = append(destSlice, tmpObj)
        mu.Unlock()
    }(myObject)
}
wg.Wait()

Penyelesaian alternatif adalah dengan menggunakan saluran ke mana goroutine menghantar nilai untuk ditambahkan. Goroutine khusus boleh mengendalikan penerimaan nilai ini dan melaksanakan operasi tambah.

Ringkasnya, manakala elemen hirisan adalah pembolehubah berbeza dan boleh diakses serentak tanpa penyegerakan, pengepala hirisan memerlukan penyegerakan untuk mengelakkan perlumbaan data semasa operasi tambah serentak.

Atas ialah kandungan terperinci Adakah Tambah dalam Go Thread-Safe Apabila Digunakan dengan Goroutines?. 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