Hello everyone, I am fried fish.
Remember that I wrote an article before " Why doesn't Go support reentrant locks? " article, mainly to introduce the process of being cruelly rejected by friends who have experience in other languages and want Go to support reentrant locks.
There will always be times when the boss can't be beaten, although it is not a reentrant lock. But in Go1.18, a new method of trying to acquire a lock (TryLock) was implemented, which is also a bit like that.
Today, Fried Fish takes everyone to learn about "he" who has been tossed 3 times.
background
The introduction of new functions must involve user scenarios. In 2018, @deanveloper mentioned a classic loading scenario: I need to load several very large files, and I want a progress bar to show how far I am from the completion time. .
He considers that this progress bar can be implemented using TryLock very well. The following 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()
}
}
The basic logic of the above code is to continuously update the counter, and then try to acquire the lock to achieve his scrolling loading progress bar.
Because the big guys thought it would be better to use channel+select-default, this user case was not enough to support the increase of TryLock functions, and was rejected again.
fight again
After a lot of discussions in 2013 and 2018, the time came to 2021 again. @TyeMcQueen gave some examples of a large number of h2 libraries, and expressed some expectations that the TryLock method would be better.
But it was also rejected, and Russ Cox objected because:
- Mutexes are used to protect invariants. If the lock is held by someone else, you have nothing to say about the invariant.
- The TryLock method encourages imprecise thinking about locks; it encourages assumptions about invariants, which may or may not be true. This eventually became its own source of competition.
turn over
In the first few failed cases, Russ Cox felt that the cases given were not convincing enough to justify the addition of the TryLock family of methods.
There are more and more people who think they need to be added, and Dmitry Vyukov, the big guy behind Google, gave the following case:
Indicates that software libraries such as gvisor, v.io/x/lib/nsync, trivago/tgo and other software libraries all use such methods of TryLock, and the implementation is basically the same as the simulation code.
Eventually Russ Cox relented, saying, "Everyone agrees it's unfortunate, but sometimes necessary," feeling reluctantly agreed.
The consideration is to give an official implementation, rather than the emergence of various third-party TryLock methods, which is inefficient and repeated implementation.
The overall timeline of history is as follows:
- In 2013 @lukescott proposed " sync: mutex.TryLock ", which was 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 and then accepted.
- In 2022, since the previous Go1.17 features have been frozen, Go1.18 is scheduled to be released (March).
new method sync.TryLock
In the upcoming Go1.18, the related methods of the TryLock series are mainly added to the sync standard library.
As shown below:
- Mutex.TryLock: Attempt to lock the mutex and return whether it was successful.
- RWMutex.TryLock: Attempt to lock the read-write lock and return whether it was successful.
- RWMutex.TryRLock. Attempt to lock the read lock and return whether it succeeded.
Official reminder: Although the scene of using TryLock does exist. But should be rare, using TryLock can often be a sign of a deeper problem.
Summarize
In Go1.18, the TryLock method of trying to acquire locks finally landed. The existence of this method has advantages and disadvantages. For example, it may become a common judgment of if-else in the future, and it can also avoid the long-term hold caused by many lock blocking.
However, in terms of application design, the use of this method is problematic and requires special attention and thinking.
Not easy, after 9 years.
If you have any questions, please feedback and exchange in the comment area. The best relationship between is to achieve . Your likes is the biggest driving force for Fried Fish . Thank you for your support.
The article continues to be updated, you can read it on WeChat search [brain fried fish], this article GitHub github.com/eddycjy/blog has been included, learn Go language can see Go learning map and route
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。