Maison  >  Article  >  développement back-end  >  Comment les WaitGroups et les Mutex peuvent-ils être utilisés pour obtenir une exclusion mutuelle entre des goroutines concurrentes dans Go ?

Comment les WaitGroups et les Mutex peuvent-ils être utilisés pour obtenir une exclusion mutuelle entre des goroutines concurrentes dans Go ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-03 22:02:03362parcourir

How can WaitGroups and Mutexes be used to achieve mutual exclusion between concurrent goroutines in Go?

Exclusion mutuelle des goroutines concurrentes à l'aide de WaitGroup et des mutex

Pour parvenir à l'exclusion mutuelle des goroutines concurrentes dans Go, où une seule goroutine à la fois peut exécuter certains codes, nous pouvons exploiter une combinaison de WaitGroup et de mutex.

WaitGroup est un primitive de synchronisation qui nous permet d'attendre qu'un groupe de goroutines termine son exécution avant de continuer. Les mutex, quant à eux, fournissent un mécanisme de verrouillage d'exclusion mutuelle, garantissant qu'une section critique du code n'est pas exécutée simultanément par plusieurs goroutines.

Considérez l'exemple de code suivant :

<code class="go">package main

import (
    "fmt"
    "rand"
    "sync"
)

var (
    mutex1, mutex2, mutex3 sync.Mutex
    wg sync.WaitGroup
)

func Routine1() {
    mutex1.Lock()
    defer mutex1.Unlock() // Ensure mutex is always unlocked before returning
    // do something

    // Sending and printing events should be mutually exclusive
    for i := 0; i < 200; i++ {
        mutex2.Lock()
        defer mutex2.Unlock()
        mutex3.Lock()
        defer mutex3.Unlock()
        fmt.Println("value of z")
    }

    // do something
}

func Routine2() {
    mutex2.Lock()
    defer mutex2.Unlock()
    // do something

    // Sending and printing events should be mutually exclusive
    for i := 0; i < 200; i++ {
        mutex1.Lock()
        defer mutex1.Unlock()
        mutex3.Lock()
        defer mutex3.Unlock()
        fmt.Println("value of z")
    }

    // do something
}

func Routine3() {
    mutex3.Lock()
    defer mutex3.Unlock()
    // do something

    // Sending and printing events should be mutually exclusive
    for i := 0; i < 200; i++ {
        mutex1.Lock()
        defer mutex1.Unlock()
        mutex2.Lock()
        defer mutex2.Unlock()
        fmt.Println("value of z")
    }

    // do something
}

func main() {
    wg.Add(3)
    go Routine1()
    go Routine2()
    Routine3()
    wg.Wait() // Wait for all goroutines to complete
}</code>

Dans ce code, nous avons trois goroutines distinctes (Routine1, Routine2 et Routine3) qui effectuent toutes certaines opérations simultanément. Cependant, nous voulons nous assurer que certaines sections du code (les événements d'envoi et d'impression) sont exécutées sans interférence d'autres goroutines.

Nous y parvenons en utilisant des mutex. Nous définissons trois mutex (mutex1, mutex2 et mutex3) et acquérons le verrou pour le mutex approprié avant d'exécuter la section critique. Lorsqu'un mutex est verrouillé par une goroutine, les autres goroutines tentant d'acquérir le même verrou seront bloquées jusqu'à ce qu'il devienne disponible.

En verrouillant et déverrouillant les mutex appropriés, nous garantissons qu'une seule goroutine peut exécuter la section critique. à un moment donné. Cela empêche l'exécution simultanée de ces sections de code et maintient une exclusion mutuelle entre les goroutines.

Enfin, nous employons un WaitGroup pour garantir que la fonction principale ne se termine pas tant que les trois goroutines n'ont pas terminé leur exécution. Cela nous permet de synchroniser les goroutines et de contrôler le déroulement du programme.

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!

Déclaration:
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