Hello, I’m fried fish.

Remember I wrote a post about why Go doesn’t support reentrant locking? The article mainly introduces the experience of friends who have experience in other languages and want to support reentrant lock, but were brutally rejected.

There will always be a problem with the big guy, although it is not reentrant lock. But in Go1.18, a new method of trylocking was implemented, which is a bit like that.

Today, fried fish takes us to learn the “him” who has been tortured for three times.

background

When it comes to new features, which will definitely involve user scenarios, back in 2018, @deanveloper brought up a classic loading scenario: loading several very large files and wanting a progress bar to show how far I am from finishing.

He considers the bar to be a good use of TryLock. Here is his sample code:

func (b *ProgressBar) Add(n int) {
    atomic.AddInt64(&b.Progress, int64(n))

    if b.Progress >= b.Max {
        b.once.Do(b.updateClientsDone)
        return
    }

    if b.pctMx.TryLock() {
        defer b.pctMx.Unlock()
        b.updateClients()
    }
}
Copy the code

The basic logic of the above code is to constantly update the counter and then implement his scrolling loading progress bar by trying to acquire the lock.

This user case is not sufficient to support the increase of TryLock’s functionality, so it was rejected again because they thought it would be better to use channel+select-default.

Fight again

After several extensive discussions in 2013, 2018, and again in 2021, @Tyemcqueen gave some examples of a large H2 library to show some hope that the TryLock approach would be better.

But it was also rejected, and Russ Cox objected because:

  • Mutex is used to protect invariants. If the lock is held by someone else, there’s nothing you can say about invariants.
  • The TryLock method encourages imprecise thinking about locks; It encourages assumptions about invariants that may or may not be true. This eventually became its own source of competition.

Roll over

In the first few failed cases, Russ Cox felt that the case presented was not enough to justify the addition of the TryLock family of methods.

As more and more people feel the need to add, Google boss Dmitry Vyukov gives the following example:

Libraries such as Gvisor, V.io /x/lib/nsync, trivago/tgo, etc. all use TryLock, which is basically the same as the emulation code.

Finally Russ Cox relented, saying, “We can all agree that this is unfortunate, but sometimes necessary,” and reluctantly agreed.

Considering an official implementation, rather than the various third-party TryLock methods, would be inefficient and duplicative.

The overall timeline of history is as follows:

  • Sync: Mutex.trylock was proposed by @Lukescott in 2013 and rejected.
  • In 2018, @deanveloper proposed proposal: Add Sync.mutex.trylock, which was rejected.
  • In 2021, @Tyemcqueen proposed Sync: Add Mutex.TryLock, which was first rejected, then accepted.
  • In 2022, due to the previous Go1.17 feature freeze, it is scheduled to be released in Go1.18 (March).

New method for the sync. TryLock

In the upcoming release of Go1.18, the TryLock family of related methods will be added to the sync standard library.

The diagram below:

  • Mutex.TryLock: An attempt was made to lock the Mutex.
  • Rwmutex. TryLock: Attempts to lock the read/write lock and returns whether it succeeded.
  • RWMutex TryRLock. Try locking the read lock and check whether it was locked successfully.

Official caution: Though TryLock does exist. But should be rare, the use of TryLock can often be a sign of deeper problems.

conclusion

In Go1.18, the TryLock method of trying to acquire locks has finally landed, and its existence has both advantages and disadvantages. It is likely to become a common if-else judgment in the future, and can also avoid the long hold caused by many lock blocks.

However, in terms of application design, the use of this method is sometimes problematic and requires special attention and consideration.

Not easy, after nine years.

If you have any questions, welcome feedback and communication in the comments section. The best relationship is mutual achievement. Your praise is the biggest motivation for the creation of fried fish, thank you for your support.

This article is constantly updated. You can read it on wechat by searching “Brain into fried fish”. GitHub github.com/eddycjy/blo… Already included, learning Go language can see Go learning map and route, welcome Star urged more.