Home  >  Article  >  Backend Development  >  Print map object when it is locked by mutex

Print map object when it is locked by mutex

PHPz
PHPzforward
2024-02-10 12:36:09832browse

Print map object when it is locked by mutex

php editor Xiaoxin is here to introduce to you a practical tip about mutex locks: how to print the map object when the map object is locked by the mutex lock. A mutex is a mechanism used to protect shared resources by ensuring that only one thread can access the locked resource at a time. In this article, we will explore how to use a mutex lock to protect a map object and print out the map contents when the object is locked to better understand the use of mutex locks and access to map objects.

Question content

I'm not sure why the mutex isn't working as I expect. Any suggestions will be helpful to me.

This is my 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)
}

When I run this, I get strange output.

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]

I expect to see a increase to 1,2,3,4

in some logs

When I remove the comments in the inc function; I can see the expected logs.

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]

Solution

In this loop:

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 operates outside the mutex. Two goroutines try to increment "a" simultaneously, one of them increments and then waits. When that increment function returns, the second function comes in and increments, then the println in the first function runs, and then the println in the second function prints the same thing.

So the mutex works as expected, but you are printing outside the area protected by the mutex.

The above is the detailed content of Print map object when it is locked by mutex. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete