Heim >Backend-Entwicklung >Golang >Kartenobjekt drucken, wenn es durch Mutex gesperrt ist

Kartenobjekt drucken, wenn es durch Mutex gesperrt ist

PHPz
PHPznach vorne
2024-02-10 12:36:09861Durchsuche

Kartenobjekt drucken, wenn es durch Mutex gesperrt ist

Der PHP-Editor Xiaoxin ist hier, um Ihnen einen praktischen Tipp zu Mutex-Sperren vorzustellen: So drucken Sie das Kartenobjekt, wenn das Kartenobjekt durch die Mutex-Sperre gesperrt ist. Ein Mutex ist ein Mechanismus zum Schutz gemeinsam genutzter Ressourcen, indem sichergestellt wird, dass jeweils nur ein Thread auf die gesperrte Ressource zugreifen kann. In diesem Artikel erfahren Sie, wie Sie mit einer Mutex-Sperre ein Kartenobjekt schützen und den Karteninhalt ausdrucken, wenn das Objekt gesperrt ist, um die Verwendung von Mutex-Sperren und den Zugriff auf Kartenobjekte besser zu verstehen.

Frageninhalt

Ich bin mir nicht sicher, warum Mutexe nicht wie erwartet funktionieren. Alle Vorschläge werden mir hilfreich sein.

Das ist mein Code.

package main

import (
    "fmt"
    "sync"
    "time"
)

type container struct {
    mu       sync.mutex
    counters map[string]int
}

func (c *container) inc(name string) {
    c.mu.lock()
    defer c.mu.unlock()
    c.counters[name]++
    
    // fmt.println("in", name, c.counters) 
    // this print is doing tricks between goroutines
    time.sleep(time.second)
}

func main() {
    c := container{

        counters: map[string]int{"a": 0, "b": 0},
    }

    var wg sync.waitgroup

    doincrement := func(name string, n int) {
        for i := 0; i < n; i++ {
            c.inc(name)
            fmt.println(name, c.counters)
        }
        wg.done()
    }

    wg.add(3)
    go doincrement("a", 2)
    go doincrement("b", 2)
    go doincrement("a", 2)

    wg.wait()
    fmt.println(c.counters)
}

Wenn ich das ausführe, erhalte ich eine seltsame Ausgabe.

a map[a:2 b:0]
a map[a:2 b:0]
b map[a:2 b:1]
a map[a:4 b:1]
a map[a:4 b:1]
b map[a:4 b:2]
map[a:4 b:2]

Ich erwarte in einigen Protokollen einen Anstieg a auf 1,2,3,4

Wenn ich den inc-Kommentar in der Funktion entferne; Ich kann die erwarteten Protokolle sehen.

in a map[a:1 b:0]
a map[a:1 b:0]
in a map[a:2 b:0]
a map[a:2 b:0]
in b map[a:2 b:1]
b map[a:2 b:1]
in a map[a:3 b:1]
a map[a:3 b:1]
in a map[a:4 b:1]
a map[a:4 b:1]
in b map[a:4 b:2]
b map[a:4 b:2]
map[a:4 b:2]

Lösung

In dieser Schleife:

for i := 0; i < n; i++ {
            c.inc(name)  ---> This runs with mutex locked
            fmt.Println(name, c.counters)  --> This runs with mutex unlocked
}

println läuft außerhalb des Mutex. Zwei Goroutinen versuchen gleichzeitig, „a“ zu erhöhen, eine von ihnen erhöht und wartet dann. Wenn diese Inkrementierungsfunktion zurückkehrt, kommt die zweite Funktion und inkrementiert, dann wird println in der ersten Funktion ausgeführt, und dann druckt println in der zweiten Funktion dasselbe.

Der Mutex funktioniert also wie erwartet, aber Sie drucken außerhalb des durch den Mutex geschützten Bereichs.

Das obige ist der detaillierte Inhalt vonKartenobjekt drucken, wenn es durch Mutex gesperrt ist. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen