Go语言 当Map对象被互斥锁锁定时打印该Map对象[重复]

xsuvu9jc  于 2022-12-07  发布在  Go
关注(0)|答案(1)|浏览(154)

此问题在此处已有答案

Race condition when printing struct field even with mutex(2个答案)
5天前关闭。
此帖子已在4天前编辑并提交审核,无法重新打开帖子:
原始关闭原因未解决
我不知道为什么互斥锁不能像我预期的那样工作。任何建议都会对我有帮助。
这是我的代码。

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

当我运行这个的时候,我得到了奇怪的输出。

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]

我希望在一些日志中可以看到a增加到1,2,3,4
当我在inc函数中删除注解时;我可以看到预期的日志。

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]
lb3vh1jj

lb3vh1jj1#

在此循环中:

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函数在互斥锁外运行,两个goroutine试图同时递增“a”,其中一个递增然后等待,当递增函数返回时,第二个goroutine进入并递增,然后第一个goroutine的Println函数运行,然后第二个goroutine的Println函数输出同样的结果。
因此,互斥锁按预期工作,但您在互斥锁保护的区域之外打印。

相关问题