Maison >développement back-end >Golang >Pourquoi la condition contenue dans la section mutex ne se bloque-t-elle pas dans cet exemple golang ?

Pourquoi la condition contenue dans la section mutex ne se bloque-t-elle pas dans cet exemple golang ?

WBOY
WBOYavant
2024-02-13 18:06:10912parcourir

为什么在这个 golang 示例中,互斥体部分中包含的条件不会出现死锁?

Dans cet exemple Golang, la raison pour laquelle un blocage ne se produira pas avec les conditions contenues dans la partie mutex est parce que le mutex implémente l'accès aux ressources partagées via les méthodes `Lock()` et `Unlock()` Accès mutuellement exclusif . Lorsqu'une goroutine appelle la méthode `Lock()`, si le mutex est déjà verrouillé par une autre goroutine, la goroutine sera bloquée jusqu'à ce que le mutex soit libéré. Ce mécanisme de blocage garantit que lorsque le mutex est verrouillé, plusieurs goroutines n'accéderont pas aux ressources partagées en même temps, évitant ainsi l'apparition d'un blocage. Ainsi, dans cet exemple, grâce à l’utilisation correcte du mutex, la condition ne sera pas bloquée.

Contenu de la question

J'ai vu cet exemple lors d'une formation chez O'Reilly. Il existe une condition qui devrait empêcher widgetInventory de devenir négatif. L'exemple fonctionne, mais je ne comprends pas pourquoi le programme ne se bloque pas lorsque makeSales obtient le mutex et que widgetInventory vaut 0.

var (
    wg sync.WaitGroup
    mutex = sync.Mutex{}
    widgetInventory int32= 1000
    newPurchase = sync.NewCond(&mutex)
)

func main() {
    fmt.Println("Starting inventory count = ", widgetInventory)
    wg.Add(2)
    go makeSales()
    go newPurchases()
    wg.Wait()
    fmt.Println("Ending inventory count = ", widgetInventory)
}

func makeSales() {
    for i := 0; i < 3000; i++ {
        mutex.Lock()
        if widgetInventory-100 < 0{
            newPurchase.Wait()
        }
        widgetInventory -= 100
        fmt.Println(widgetInventory)
        mutex.Unlock()
    }
    wg.Done()
}

func newPurchases() {
    for i := 0; i < 3000; i++ {
        mutex.Lock()
        widgetInventory+= 100
        fmt.Println(widgetInventory)
        newPurchase.Signal()
        mutex.Unlock()
    }
    wg.Done()
}

Je m'attendais à ce que le code se bloque lorsque makeSales obtient le mutex et que widgetInventory est égal à 0.

Solution

Je n'ai pas remarqué que la condition était associée au mutex : newPurchase =sync.NewCond(&mutex) La saisie de .Wait() déverrouille le mutex et tente de le réacquérir lorsque le signal de condition est reçu.

condition.Wait() ne fonctionne que lors de l'acquisition d'un mutex, donc cela fonctionne au prix d'un code moins lisible :-)

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer