Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Mengelakkan Keadaan Perlumbaan Apabila Menggunakan sync.Cond untuk Menunggu Bersyarat?

Bagaimana untuk Mengelakkan Keadaan Perlumbaan Apabila Menggunakan sync.Cond untuk Menunggu Bersyarat?

Susan Sarandon
Susan Sarandonasal
2024-11-10 14:21:02865semak imbas

How to Avoid Race Conditions When Using sync.Cond for Conditional Waiting?

Dengan Betul Menggunakan sync.Cond for Conditional Waiting

Sambil meneroka kefungsian sync.Cond, ia menjadi jelas bahawa keadaan perlumbaan boleh timbul antara mengunci penyegerakan.Mutex dan memanggil cond.Tunggu. Untuk menunjukkan ini, kelewatan buatan telah diperkenalkan ke dalam goroutine utama, mensimulasikan keadaan perlumbaan:

package main

import (
    "sync"
    "time"
)

func main() {
    var m sync.Mutex
    var c = sync.NewCond(&m)

    go func() {
        time.Sleep(1 * time.Second)
        c.Broadcast()
    }()

    m.Lock()
    time.Sleep(2 * time.Second)
    c.Wait()
}

Melaksanakan kod ini mengakibatkan panik buntu kerana goroutine menunggu keadaan yang belum diisyaratkan lagi .

Menangani Keadaan Perlumbaan

Yang betul pendekatan untuk mengelakkan keadaan perlumbaan ini adalah untuk memastikan penyegerakan.Mutex dikunci sebelum memanggil cond.Tunggu. Ini menghalang goroutine lain daripada mengubah suai data yang dikongsi semasa goroutine semasa menunggu dengan syarat:

package main

import (
    "sync"
    "time"
)

func main() {
    var m sync.Mutex
    var c = sync.NewCond(&m)

    go func() {
        time.Sleep(1 * time.Second)
        m.Lock()
        c.Broadcast()
        m.Unlock()
    }()

    m.Lock()
    c.Wait()
    m.Unlock()
}

Konstruk Penyegerakan Alternatif

Semasa penyegerakan.Cond boleh berguna dalam senario di mana berbilang goroutine menunggu sumber yang dikongsi tersedia, adalah penting untuk mempertimbangkan penyegerakan alternatif primitif. Sebagai contoh, jika anda mempunyai hubungan satu dengan satu antara penulis dan pembaca, penyegerakan.Mutex mungkin memadai untuk komunikasi:

var sharedRsc = make(map[string]interface{})

func main() {
    m := sync.Mutex{}
    go func() {
        m.Lock()
        sharedRsc["rsc1"] = "foo"
        m.Unlock()
    }()

    m.Lock()
    fmt.Println(sharedRsc["rsc1"])
    m.Unlock()
}

Dalam kes di mana berbilang pembaca terlibat, saluran menawarkan yang lebih cekap dan penyelesaian berskala untuk menghantar data.

Atas ialah kandungan terperinci Bagaimana untuk Mengelakkan Keadaan Perlumbaan Apabila Menggunakan sync.Cond untuk Menunggu Bersyarat?. 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