您现在的位置是:亿华云 > IT科技
Go 为什么不支持可重入锁?
亿华云2025-10-05 08:04:24【IT科技】2人已围观
简介本文转载自微信公众号「脑子进煎鱼了」,作者陈煎鱼。转载本文请联系脑子进煎鱼了公众号。大家好,我是煎鱼。程序里的锁,是很多小伙伴在写分布式应用时用的最多的一个利器之一。使用 Go 的同学里,绝大部分都有
本文转载自微信公众号「脑子进煎鱼了」,不支作者陈煎鱼。重入转载本文请联系脑子进煎鱼了公众号。不支
大家好,重入我是不支煎鱼。
程序里的重入锁,是不支很多小伙伴在写分布式应用时用的最多的一个利器之一。
使用 Go 的重入同学里,绝大部分都有其他语言的不支经验,就会对其中一点有疑惑,重入那就是不支 Go 里的锁,竟然不支持可重入?重入
为此,今天煎鱼带大家一起来了解这里的不支设计考量,看看为什么。重入
可重入锁
如果对已经上锁的不支普通互斥锁进行 “加锁” 操作,其结果要么失败,要么会阻塞至解锁。
锁的场景如下:
在加锁上:如果是可重入互斥锁,当前尝试加锁的线程如果就是持有该锁的云服务器提供商线程时,加锁操作就会成功。 在解锁上:可重入互斥锁一般都会记录被加锁的次数,只有执行相同次数的解锁操作才会真正解锁。简单来讲,可重入互斥锁是互斥锁的一种,同一线程对其多次加锁不会产生死锁,又或是导致阻塞。
不同语言间实现可能或多或少有些区别,但大体意思差不多。
请你想一下,Go 是怎么样的呢?
Go 支持情况
我们看到以下这个 Go 互斥锁例子:
var mu sync.Mutex func main() { mu.Lock() mu.Lock() }这段 Go 程序会阻塞吗?不会,会报以下错误:
fatal error: all goroutines are asleep - deadlock!Go 显然是不支持可重入互斥锁的。
官方回复
Go 设计原则
在工程中使用互斥的根本原因是:为了保护不变量,也可以用于保护内、外部的不变量。
基于此,Go 在互斥锁设计上会遵守这几个原则。如下:
在调用 mutex.Lock 方法时,要保证这些变量的不变性保持,服务器租用不会在后续的过程中被破坏。 在调用 mu.Unlock 方法时,要保证: 程序不再需要依赖那些不变量。 如果程序在互斥锁加锁期间破坏了它们,则需要确保已经恢复了它们。不支持的原因
讲了 Go 自己的设计原则后,那为什么不支持可重入呢?
其实 Russ Cox 于 2010 年在《Experimenting with GO[1]》就给出了答复,认为递归(又称:重入)互斥是个坏主意,这个设计并不好。
我们可以结合官方的例子来理解。
如下:
func F() { mu.Lock() ... do some stuff ... G() ... do some more stuff ... mu.Unlock() } func G() { mu.Lock() ... do some stuff ... mu.Unlock() }在上述代码中,我们在 F 方法中调用 mu.Lock 方法加上了锁。如果支持可重入锁,接着就会进入到 G 方法中。
此时就会有一个致命的问题,你不知道 F 和 G 方法加锁后是不是做了什么事情,从而导致破坏了不变量,毕竟随手起几个协程做点坏事,也是完全可能的。
这对于 Go 是无法接受的,可重入的高防服务器设计违反了前面所提到的设计理念,也就是:“要保证这些变量的不变性保持,不会在后续的过程中被破坏”。
基于上述原因,Go 官方团队选择了没有支持该项特性。
总结
Go 互斥锁没有支持可重入锁的设计,也是喜欢的大道至简的思路了,可能的干扰比较多,不如直接简单的来。
你在工作过程中有没有类似的疑惑呢,欢迎大家在评论区留言和交流:)
参考资料
[1]Experimenting with GO: https://groups.google.com/g/golang-nuts/c/XqW1qcuZgKg/m/Ui3nQkeLV80J
很赞哦!(953)
相关文章
- Status、Creation Date、Expiration Date
- 甲骨文索要88亿美元安卓系统Java版权费:谷歌寻求驳回
- 写给技术人员:停止学习框架,要专注基础知识
- 支付宝小程序正式面向个人开发者开放公测
- 细说API – 认证、授权和凭证
- 苏宁发票中心自助开票,测试自动化减负初实践
- 工作996,生病ICU?央视财经:年轻人该如何奋斗?
- 为了避免将来给我们的个人站长带来的麻烦,在选择域名后缀时,我们的站长最好省略不稳定的后缀域名,比如n,因为我们不知道策略什么时候会改变,更不用说我们将来是否还能控制这个域名了。因此,如果站长不是企业,或者有选择的话,如果不能选择域名的cn类,最好不要选择它。
- 世界顶级的程序员们告诉你:这些书都是你应该读的