php小编小新在这里向大家介绍一个关于互斥锁的实用技巧:当地图对象被互斥锁锁定时,如何打印地图对象。互斥锁是一种用于保护共享资源的机制,确保同时只有一个线程可以访问被锁定的资源。在本文中,我们将探讨如何使用互斥锁来保护地图对象,并在对象被锁定时打印出地图内容,以便更好地理解互斥锁的使用和地图对象的访问。
问题内容
我不确定为什么互斥体没有按我的预期工作。任何建议都会对我有帮助。
这是我的代码。
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]
解决方法
在此循环中:
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”,其中一个递增然后等待。当该增量函数返回时,第二个函数进入并递增,然后第一个函数中的 println 运行,然后第二个函数中的 println 打印相同的内容。
因此,互斥体按预期工作,但您正在互斥体保护的区域之外进行打印。
以上就是当地图对象被互斥锁锁定时打印地图对象的详细内容,更多请关注编程网其它相关文章!