成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go 為什么不支持可重入鎖?

開發 后端
使用 Go 的同學里,絕大部分都有其他語言的經驗,就會對其中一點有疑惑,那就是 Go 里的鎖,竟然不支持可重入?

[[440472]]

本文轉載自微信公眾號「腦子進煎魚了」,作者陳煎魚。轉載本文請聯系腦子進煎魚了公眾號。

大家好,我是煎魚。

程序里的鎖,是很多小伙伴在寫分布式應用時用的最多的一個利器之一。

使用 Go 的同學里,絕大部分都有其他語言的經驗,就會對其中一點有疑惑,那就是 Go 里的鎖,竟然不支持可重入?

為此,今天煎魚帶大家一起來了解這里的設計考量,看看為什么。

可重入鎖

如果對已經上鎖的普通互斥鎖進行 “加鎖” 操作,其結果要么失敗,要么會阻塞至解鎖。

鎖的場景如下:

  • 在加鎖上:如果是可重入互斥鎖,當前嘗試加鎖的線程如果就是持有該鎖的線程時,加鎖操作就會成功。
  • 在解鎖上:可重入互斥鎖一般都會記錄被加鎖的次數,只有執行相同次數的解鎖操作才會真正解鎖。

簡單來講,可重入互斥鎖是互斥鎖的一種,同一線程對其多次加鎖不會產生死鎖,又或是導致阻塞。

不同語言間實現可能或多或少有些區別,但大體意思差不多。

請你想一下,Go 是怎么樣的呢?

Go 支持情況

我們看到以下這個 Go 互斥鎖例子:

  1. var mu sync.Mutex 
  2.  
  3. func main() { 
  4.  mu.Lock() 
  5.  mu.Lock() 

這段 Go 程序會阻塞嗎?不會,會報以下錯誤:

  1. fatal error: all goroutines are asleep - deadlock! 

Go 顯然是不支持可重入互斥鎖的。

官方回復

Go 設計原則

在工程中使用互斥的根本原因是:為了保護不變量,也可以用于保護內、外部的不變量。

基于此,Go 在互斥鎖設計上會遵守這幾個原則。如下:

  • 在調用 mutex.Lock 方法時,要保證這些變量的不變性保持,不會在后續的過程中被破壞。
  • 在調用 mu.Unlock 方法時,要保證:
    • 程序不再需要依賴那些不變量。
    • 如果程序在互斥鎖加鎖期間破壞了它們,則需要確保已經恢復了它們。

不支持的原因

講了 Go 自己的設計原則后,那為什么不支持可重入呢?

其實 Russ Cox 于 2010 年在《Experimenting with GO[1]》就給出了答復,認為遞歸(又稱:重入)互斥是個壞主意,這個設計并不好。

我們可以結合官方的例子來理解。

如下:

  1. func F() { 
  2.         mu.Lock() 
  3.         ... do some stuff ... 
  4.         G() 
  5.         ... do some more stuff ... 
  6.         mu.Unlock() 
  7.  
  8. func G() { 
  9.         mu.Lock() 
  10.         ... do some stuff ... 
  11.         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

 

責任編輯:武曉燕 來源: 腦子進煎魚了
相關推薦

2021-10-27 07:15:36

Go 循環引用

2021-12-09 10:51:47

Go繼承

2024-01-01 08:10:40

Go語言map

2024-01-05 08:45:35

Go語言map

2024-05-28 08:55:52

2023-01-28 08:05:32

轉換Go泛型

2021-11-08 11:02:01

Go函數重載

2023-02-26 23:36:08

PHPGo函數

2024-03-08 08:51:59

Gomain函數

2020-07-22 08:01:41

Python開發運算符

2020-10-09 06:48:19

Pythonswitch語句

2024-03-12 09:13:28

Go語言main

2021-02-01 13:53:53

StringlongJava

2021-07-13 08:09:34

微博推特評論

2023-04-03 11:21:29

PythonGoRust

2025-06-26 02:22:00

GoProtobuf標簽

2009-03-12 08:42:38

AndroidWMMTK

2021-06-11 00:03:31

鴻蒙智能手機

2021-08-02 09:31:20

Python工具代碼

2014-06-05 15:16:49

Linux開源Flash
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 激情三区| 国产2区 | 国产成人精品a视频一区www | 一级片网址 | 天天久久 | 午夜成人免费电影 | 蜜桃视频一区二区三区 | 日本不卡一区二区三区 | 日韩在线播放第一页 | 国产98色在线 | 成人福利网站 | 国产一级视屏 | 国产成人99av超碰超爽 | 国产精品美女久久久久久免费 | 久久久久久久一区 | 精品欧美一区二区三区久久久 | 色一情一乱一伦一区二区三区 | 毛片久久久 | 一区二区三区在线播放 | 久久精品av | 午夜影视 | 中文字幕91av| 亚洲精品精品 | 日韩一区在线视频 | www.亚洲一区二区三区 | 四虎影院免费在线 | 日韩国产精品一区二区三区 | 久久久久久久97 | 天天干夜夜操 | 91久久夜色精品国产网站 | 久久最新网址 | 欧美99 | 蜜臀av日日欢夜夜爽一区 | 亚洲啪啪 | 国产一区二区成人 | 久久国产综合 | 国产在线一区二区三区 | 99pao成人国产永久免费视频 | 国产成人综合在线 | 精品乱码久久久久 | 免费日韩网站 |