This is the 27th day of my participation in the August More Text Challenge

This article appears in my column:Let’s Golang

Today let’s talk about Golang’s mutex

Today let’s talk about locking. We all know that there is concurrency and there is concurrency security. Some variables cannot be accessed concurrently. For instance the deposit or withdrawal business of the bank, if can concurrently undertake, you think you put the salary of this month to the bank 2 million, your wife takes 2 million in the bank at the same time to do hairdressing. If do not use lock, amount did not change is discovered after you put, money also did not change after your wife takes money. You are panic dead, that your wife is not happy bad…….

So we need a lock here, when one person accesses the business, it locks it, and no one else can access it.

Take a look at this saving example:

var wg sync.WaitGroup
func main(a) {
    var money = 2000
    for i:=0; i<10; i++{ wg.Add(1)
        go func(a) {
            for j:=0; j<100; j++{ money +=1
            }
            wg.Done()
        }()
    }
    wg.Wait()
    fmt.Println("Final amount",money)
}
Copy the code

This example would be 10 people each depositing $100 for you. The hundred dollars were deposited in one hundred installments. That’ll give us three thousand dollars.

Let’s take a look at the results:

Final Amount 3000Copy the code

Seems to be no problem! Let’s increase the deposit amount. Let’s have 10 people each deposit $1,000, and we’ll divide that $1,000 over a thousand times, so we’ll get $12,000. Let’s see what happens!

Final amount 10366Copy the code

Is it not what we expected?

This is a concurrency security problem.

For this kind of problem, we should not allow concurrent access.

Then let’s see how to use mutex to solve these problems.

func main(a) {
    var money = 2000var mt sync.Mutex
​
    wg.Add(1)
    go func(a) {
        fmt.Println("Boda tries to tackle.")
​
        mt.Lock()
        fmt.Println("Boda made a tackle.")
​
        money -= 300
        <- time.After(10 * time.Second)
​
        mt.Unlock()
        fmt.Println(Boda threw the ball.)
        wg.Done()
    }()
​
    wg.Add(1)
    go func(a) {
        fmt.Println("Boda tries to dance")
​
        mt.Lock()
        fmt.Println("Boda dances successfully.")
​
        money -= 500
        <- time.After(10 * time.Second)
        mt.Unlock()
        fmt.Println("Boda gives up dancing.")
        wg.Done()
    }()
​
    wg.Wait()
​
}
Copy the code

The meaning of this program is that two dancers fight for the lock at the same time. If the dancer wins the lock first, Boda begins to dance. After dancing, Boda unlocks the lock. If the tackler gets the lock first, Boda starts the tackle and then dances.

The run result is

Boda attempted a steal. Boda attempted a dance. Boda threw the ballCopy the code

As you can see, Boda can’t dance until he throws the ball. That’s what the lock does, keeping Boda from getting tired of dancing and tackling.