Rumah >pembangunan bahagian belakang >Golang >Bagaimana Mengelakkan Kebuntuan Apabila Menggunakan sync.Cond in Go?

Bagaimana Mengelakkan Kebuntuan Apabila Menggunakan sync.Cond in Go?

DDD
DDDasal
2024-11-16 14:27:03413semak imbas

How to Avoid Deadlock When Using sync.Cond in Go?

Cara Menggunakan sync.Cond dengan Berkesan

Memahami Masalah

Apabila bekerja dengan sync.Cond, adalah penting untuk sedar tentang keadaan perlumbaan yang berpotensi antara mengunci dan menggunakan kaedah Tunggu. Dalam contoh yang disediakan:

import (
    "sync"
    "time"
)

func main() {
    m := sync.Mutex{}
    c := sync.NewCond(&m)
    go func() {
        time.Sleep(1 * time.Second)
        c.Broadcast()
    }()
    m.Lock()
    time.Sleep(2 * time.Second)
    c.Wait()
}

Groutine utama sengaja memperkenalkan kelewatan antara mengunci mutex dan memanggil c.Wait(). Ini menyerupai keadaan perlumbaan yang mencetuskan panik kebuntuan semasa pelaksanaan.

Menyelesaikan Keadaan Perlumbaan

Untuk mengelakkan isu ini, adalah penting untuk mendapatkan kunci secara jelas sebelum memanggil c .Tunggu(). Dengan berbuat demikian, kami memastikan Cond menunggu hanya apabila mutex yang sepadan dikunci.

Bila Menggunakan sync.Cond

Menentukan sama ada sync.Cond adalah sesuai penyegerakan primitif untuk senario anda adalah sama penting. Walaupun ia sesuai untuk senario di mana berbilang pembaca mungkin menunggu sumber yang dikongsi tersedia, penyegerakan yang lebih mudah. ​​Mutex mungkin mencukupi untuk operasi menulis dan membaca satu-sama-satu antara goroutines.

Menggunakan Saluran sebagai Alternatif

Dalam beberapa kes, saluran menyediakan kaedah pertukaran data yang lebih cekap berbanding penyegerakan.Cond. Sebagai contoh, dalam contoh di atas, saluran boleh digunakan untuk memberi isyarat apabila pengepala HTTP tersedia. Pendekatan ini mengelakkan keperluan untuk mengunci dan menunggu, menghasilkan prestasi yang lebih baik.

Contoh: Menggunakan penyegerakan.Cond

Jika penyegerakan.Cond ialah pendekatan pilihan, pertimbangkan mengikuti contoh:

var sharedRsc = make(map[string]interface{})
func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    m := sync.Mutex{}
    c := sync.NewCond(&m)
    go func() {
        c.L.Lock()
        for len(sharedRsc) == 0 {
            c.Wait()
        }
        fmt.Println(sharedRsc["rsc1"])
        c.L.Unlock()
        wg.Done()
    }()

    go func() {
        c.L.Lock()
        for len(sharedRsc) == 0 {
            c.Wait()
        }
        fmt.Println(sharedRsc["rsc2"])
        c.L.Unlock()
        wg.Done()
    }()

    c.L.Lock()
    sharedRsc["rsc1"] = "foo"
    sharedRsc["rsc2"] = "bar"
    c.Broadcast()
    c.L.Unlock()
    wg.Wait()
}

Kesimpulan

Walaupun sync.Cond menawarkan penyelesaian untuk perkongsian data dan penyegerakan, adalah penting untuk mempertimbangkan dengan teliti kesesuaian primitif ini untuk khusus anda keperluan. Memahami kemungkinan keadaan perlumbaan dan mekanisme penyegerakan alternatif boleh membantu anda menggunakan penyegerakan.Cond dengan berkesan dalam aplikasi Go anda.

Atas ialah kandungan terperinci Bagaimana Mengelakkan Kebuntuan Apabila Menggunakan sync.Cond in 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
Artikel sebelumnya:Slices: Tulang Belakang Pergi!Artikel seterusnya:Slices: Tulang Belakang Pergi!