Maison > développement back-end > Golang > Comment éviter les blocages lors de l'utilisation de sync.Cond dans Go ?

Comment éviter les blocages lors de l'utilisation de sync.Cond dans Go ?

DDD
Libérer: 2024-11-16 14:27:03
original
418 Les gens l'ont consulté

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

Comment utiliser efficacement sync.Cond

Comprendre le problème

Lorsque vous travaillez avec sync.Cond, il est crucial de soyez conscient de la condition de concurrence potentielle entre le verrouillage et l’appel de la méthode Wait. Dans l'exemple fourni :

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()
}
Copier après la connexion

La goroutine principale introduit intentionnellement un délai entre le verrouillage du mutex et l'appel de c.Wait(). Cela simule une condition de concurrence qui déclenche une panique de blocage lors de l'exécution.

Résolution de la condition de concurrence

Pour éviter ce problème, il est essentiel d'acquérir le verrou explicitement avant d'appeler c .Attendez(). Ce faisant, nous garantissons que le Cond attend uniquement lorsque le mutex correspondant est verrouillé.

Quand utiliser sync.Cond

Déterminer si sync.Cond est le approprié la primitive de synchronisation pour votre scénario est tout aussi importante. Bien qu'il soit adapté aux scénarios dans lesquels plusieurs lecteurs peuvent attendre que des ressources partagées soient disponibles, une synchronisation plus simple. Mutex peut suffire pour des opérations d'écriture et de lecture individuelles entre goroutines.

Utiliser les canaux comme un Alternative

Dans certains cas, les canaux offrent une méthode d'échange de données plus efficace que sync.Cond. Par exemple, dans l'exemple ci-dessus, un canal peut être utilisé pour signaler quand les en-têtes HTTP deviennent disponibles. Cette approche évite le besoin de verrouillage et d'attente, ce qui entraîne des performances améliorées.

Exemple : Utilisation de sync.Cond

Si sync.Cond est l'approche préférée, considérez l'option exemple suivant :

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()
}
Copier après la connexion

Conclusion

Pendant sync.Cond offre une solution de partage et de synchronisation de données, il est essentiel d'examiner attentivement l'adéquation de cette primitive à vos besoins spécifiques. Comprendre les conditions de concurrence potentielles et les mécanismes de synchronisation alternatifs peut vous aider à utiliser efficacement sync.Cond dans vos applications Go.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal