还记得我之前写过一篇《Go 为什么不支持可重入锁?》的文章,主要是介绍有其他语言经验的小伙伴,想要 Go 支持可重入锁,被残忍拒绝的历程。
创新互联建站专业为企业提供临夏州网站建设、临夏州做网站、临夏州网站设计、临夏州网站制作等企业网站建设、网页设计与制作、临夏州企业网站模板建站服务,十多年临夏州做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
来自《Go 为什么不支持可重入锁?》
大佬总会有拗不过的时候,虽然不是可重入锁。但在 Go1.18 实现了尝试获取锁(TryLock)的新方法,也有点那味道了。
今天煎鱼带大家学习被折腾了 3 回的 “他”。
提新功能,肯定涉及用户场景,时间来到 2018 年,@deanveloper 就提了一个经典的加载场景:需加载几个非常大的文件,想要一个进度条来显示我离完成的时间有多远。
他考虑这个进度条可以很好地利用 TryLock 来实现,以下为他的示例代码:
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()
}
}
上述代码的基本逻辑,就是不断地更新计数器,接着通过尝试获取锁,来实现他的滚动加载进度条。
由于大佬们认为他这个用 channel+select-default 来做,会更好,这个用户案例不够足矣支撑 TryLock 的功能增加,再度被拒绝。
经过 2013、2018 年的几次大量讨论,时间再度来到 2021 年,@TyeMcQueen 举例了大量 h2 库的一些例子,表示有 TryLock 方法会更好的一些期许。
但也被拒绝了,Russ Cox 反对的原因是:
互斥锁是用来保护不变量的。如果锁被别人持有,你就没有什么可以说的不变量了。
TryLock 方法鼓励对锁进行不精确的思考;它鼓励对不变量进行假设,这些假设可能是真的,也可能不是真的。这最终成为了它自己的竞赛来源。
在前几次失败的案例中,Russ Cox 认为给出的案例并不足以说服作为 TryLock 系列方法添加的理由。
认为需要添加的人越来越多,加上后面 Google 的大佬 Dmitry Vyukov 给出了如下案例:
表示像是 gvisor、v.io/x/lib/nsync、trivago/tgo 等软件库都有使用到 TryLock 的这类方法,实现与模拟代码基本一致。
最终 Russ Cox 松口,表示:“大家都同意这是不幸的,但有时是必要的”,感觉勉强答应了。
考虑的是是给一个官方实现,而非出现各种第三方 TryLock 方法,显得就很低效,重复实现了。
历史的整体时间线历程如下:
在即将发布的 Go1.18 中,主要是在 sync 标准库中新增了 TryLock 系列的相关方法。
如下图:
sync@master#Mutex.TryLock
官方特意提醒:虽然使用 TryLock 的场景确实存在。但应该是罕见的,使用 TryLock 往往可能是更深层次问题的标志。
在 Go1.18,尝试获取锁的 TryLock 方法终于落地了,该方法的存在有利有弊。像是以后可能就会成为一个 if-else 常用的判断了,也能规避掉不少锁阻塞导致的长时间 hold 住。
但从应用程序设计上来讲,该方法的使用,有的就是有问题的,需要特别的关注和思考。
分享名称:Go1.18新特性:被折腾N次的TryLock
分享URL:http://www.shufengxianlan.com/qtweb/news45/50995.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联