Hello everyone, I am fried fish.

The lock in the program is one of the most powerful tools used by many small partners when writing distributed applications.

Most of the students who use Go have experience in other languages, and they will be confused about one of them, that is Go does not support reentrant ?

To this end, today fried fish will take everyone to understand the design considerations here and see why.

Reentrant lock

If you perform a "lock" operation on an ordinary mutex that has been locked, the result will either fail or block until unlocking.

The lock scenario is as follows:

  • On locking: If it is a reentrant mutex, if the thread currently trying to lock is the thread holding the lock, the locking operation will succeed.
  • On unlocking: Reentrant mutexes generally record the number of times that they are locked, and only unlock operations that are performed the same number of times will they be unlocked.

Simply put, a reentrant mutex is a type of mutual exclusion lock. The same thread locks it multiple times without deadlock or blocking.

There may be more or less differences between different languages, but the general meaning is similar.

Please think about it, what is Go like?

Go support

We see the following example of a Go mutex:

var mu sync.Mutex

func main() {
    mu.Lock()
    mu.Lock()
}

Will this Go program block? No, the following error will be reported:

fatal error: all goroutines are asleep - deadlock!

Go obviously does not support reentrant mutexes.

Official reply

Go design principles

The fundamental reason for using mutual exclusion in engineering is: in order to protect invariants, it can also be used to protect internal and external invariants.

Based on this, Go will abide by these principles in the design of mutual exclusion locks. as follows:

  • When calling the mutex.Lock method, it is necessary to ensure that the invariance of these variables is maintained and will not be destroyed in the subsequent process.
  • When calling the mu.Unlock method, ensure that:

    • The program no longer needs to rely on those invariants.
    • If the program destroys them while the mutex is locked, you need to ensure that they have been restored.

Reasons not supported

After talking about Go's own design principles, why not support reentrancy?

In fact, Russ Cox Experimenting with GO " in 2010, thinking that recursive (also known as reentrant) mutual exclusion is a bad idea, and this design is not good.

We can combine the official examples to understand.

as follows:

func F() {
        mu.Lock()
        ... do some stuff ...
        G()
        ... do some more stuff ...
        mu.Unlock()
}

func G() {
        mu.Lock()
        ... do some stuff ...
        mu.Unlock()
}

In the above code, we F call method mu.Lock method coupled with the lock. If it supports reentrant locks, then it will enter the G method.

At this point there will be a fatal problem, you do not know F and G after locking method is not doing anything , resulting in destruction of the invariant, after all, pick from a few coroutine to do bad things, is entirely possible of.

This is unacceptable for Go. The reentrant design violates the aforementioned design concept , which is: "It is necessary to ensure that the invariance of these variables is maintained and will not be destroyed in the subsequent process."

For the above reasons, the official Go team chose not to support this feature.

Summarize

Go mutexes do not support the design of reentrant locks, and I like the idea of a simple way. There are more possible interferences, so it is better to be straightforward and simple.

Do you have similar doubts during your work? Welcome everyone to leave a message and communicate in the comment area:)

If you have any questions please comment and feedback exchange area, best relationship is mutual achievement , everybody thumbs is fried fish maximum power of creation, thanks for the support.

Article continually updated, you can head into the micro-channel search [fried] read the article GitHub github.com/eddycjy/blog already been included, Go language learning can be seen Go Learning Map and Directions , welcome Star urge more.

煎鱼
8.4k 声望12.8k 粉丝