欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go?為什么不支持可重入鎖原理解析

 更新時(shí)間:2023年08月07日 09:02:49   作者:煎魚  
這篇文章主要為大家介紹了Go?為什么不支持可重入鎖原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

程序里的鎖,是很多小伙伴在寫分布式應(yīng)用時(shí)用的最多的一個利器之一。

使用 Go 的同學(xué)里,絕大部分都有其他語言的經(jīng)驗(yàn),就會對其中一點(diǎn)有疑惑,那就是 Go 里的鎖,竟然不支持可重入?

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

可重入鎖

如果對已經(jīng)上鎖的普通互斥鎖進(jìn)行 “加鎖” 操作,其結(jié)果要么失敗,要么會阻塞至解鎖。

鎖的場景如下:

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

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

不同語言間實(shí)現(xiàn)可能或多或少有些區(qū)別,但大體意思差不多。

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

Go 支持情況

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

var mu sync.Mutex
func main() {
    mu.Lock()
    mu.Lock()
}

這段 Go 程序會阻塞嗎?不會,會報(bào)以下錯誤:

fatal error: all goroutines are asleep - deadlock!

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

官方回復(fù)

Go 設(shè)計(jì)原則

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

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

  • 在調(diào)用 mutex.Lock 方法時(shí),要保證這些變量的不變性保持,不會在后續(xù)的過程中被破壞。
  • 在調(diào)用 mu.Unlock 方法時(shí),要保證:

    • 程序不再需要依賴那些不變量。
    • 如果程序在互斥鎖加鎖期間破壞了它們,則需要確保已經(jīng)恢復(fù)了它們。

不支持的原因

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

其實(shí) Russ Cox 于 2010 年在《Experimenting with GO》就給出了答復(fù),認(rèn)為遞歸(又稱:重入)互斥是個壞主意,這個設(shè)計(jì)并不好。

我們可以結(jié)合官方的例子來理解。

如下:

func F() {
        mu.Lock()
        ... do some stuff ...
        G()
        ... do some more stuff ...
        mu.Unlock()
}
func G() {
        mu.Lock()
        ... do some stuff ...
        mu.Unlock()
}

在上述代碼中,我們在 F 方法中調(diào)用 mu.Lock 方法加上了鎖。如果支持可重入鎖,接著就會進(jìn)入到 G 方法中。

此時(shí)就會有一個致命的問題,你不知道 F 和 G 方法加鎖后是不是做了什么事情,從而導(dǎo)致破壞了不變量,畢竟隨手起幾個協(xié)程做點(diǎn)壞事,也是完全可能的。

這對于 Go 是無法接受的,可重入的設(shè)計(jì)違反了前面所提到的設(shè)計(jì)理念,也就是:“要保證這些變量的不變性保持,不會在后續(xù)的過程中被破壞”。

基于上述原因,Go 官方團(tuán)隊(duì)選擇了沒有支持該項(xiàng)特性。

總結(jié)

Go 互斥鎖沒有支持可重入鎖的設(shè)計(jì),也是喜歡的大道至簡的思路了,可能的干擾比較多,不如直接簡單的來。

以上就是Go 為什么不支持可重入鎖原理解析的詳細(xì)內(nèi)容,更多關(guān)于Go不支持可重入鎖的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • minikube部署Go應(yīng)用小結(jié)

    minikube部署Go應(yīng)用小結(jié)

    本文詳細(xì)介紹了在VMCentos7環(huán)境下使用Minikube和Kubernetes部署Go應(yīng)用的步驟,包括安裝Minikube和Kubectl、配置Docker鏡像源和私有倉庫、部署項(xiàng)目以及解決啟動過程中的常見問題,感興趣的朋友一起看看吧
    2025-03-03
  • Go語言如何實(shí)現(xiàn)將[][]byte轉(zhuǎn)為io.Reader

    Go語言如何實(shí)現(xiàn)將[][]byte轉(zhuǎn)為io.Reader

    本文主要介紹了如何在Go語言中實(shí)現(xiàn)將[][]byte轉(zhuǎn)換為io.Reader,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2025-02-02
  • Go處理json數(shù)據(jù)方法詳解(Marshal,UnMarshal)

    Go處理json數(shù)據(jù)方法詳解(Marshal,UnMarshal)

    這篇文章主要介紹了Go處理json數(shù)據(jù)的方法詳解,Marshal(),UnMarshal(),需要的朋友可以參考下
    2022-04-04
  • Go語言生成UUID的利器(github.com/google/uuid)

    Go語言生成UUID的利器(github.com/google/uuid)

    UUID是確保每個元素唯一性的重要工具,Go語言雖然在標(biāo)準(zhǔn)庫中沒有直接提供UUID生成功能,但可以通過安裝github.com/google/uuid庫來實(shí)現(xiàn),本文就來介紹一下,感興趣的可以了解一下
    2024-11-11
  • Go 1.21新增的slices包中切片函數(shù)用法詳解

    Go 1.21新增的slices包中切片函數(shù)用法詳解

    Go 1.21新增的 slices 包提供了很多和切片相關(guān)的函數(shù),可以用于任何類型的切片,本文通過代碼示例為大家介紹了部分切片函數(shù)的具體用法,感興趣的小伙伴可以了解一下
    2023-08-08
  • Golang Copier入門到入坑探究

    Golang Copier入門到入坑探究

    這篇文章主要為大家介紹了Golang Copier入門到入坑探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Go語言中io.Reader和io.Writer的詳解與實(shí)現(xiàn)

    Go語言中io.Reader和io.Writer的詳解與實(shí)現(xiàn)

    在Go語言的實(shí)際編程中,幾乎所有的數(shù)據(jù)結(jié)構(gòu)都圍繞接口展開,接口是Go語言中所有數(shù)據(jù)結(jié)構(gòu)的核心。在使用Go語言的過程中,無論你是實(shí)現(xiàn)web應(yīng)用程序,還是控制臺輸入輸出,又或者是網(wǎng)絡(luò)操作,不可避免的會遇到IO操作,使用到io.Reader和io.Writer接口。下面來詳細(xì)看看。
    2016-09-09
  • 執(zhí)行g(shù)o?vendor第三方包版本沖突問題解決

    執(zhí)行g(shù)o?vendor第三方包版本沖突問題解決

    這篇文章主要為大家介紹了執(zhí)行g(shù)o?vendor時(shí),第三方包go版本沖突問題的解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Go Web框架gin的入門教程

    Go Web框架gin的入門教程

    本篇文章主要介紹了Go Web框架gin的入門教程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Go?語言入門學(xué)習(xí)之時(shí)間包

    Go?語言入門學(xué)習(xí)之時(shí)間包

    這篇文章主要介紹了Go?語言入門學(xué)習(xí)之時(shí)間包,GO?語言提供了???time??包來測量和顯示時(shí)間,下文關(guān)于GO時(shí)間包的相關(guān)介紹需要的小伙伴可以參考一下
    2022-04-04

最新評論