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() }
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() }
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!