日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一篇學會Go的TryLock實現(xiàn)

在之前的設計中,當鎖被占有,其他 goroutine 嘗試獲取鎖時會被阻塞。這種方式當然是合理的,但是在某些情況下,或許我們希望在獲取鎖失敗時,并不想停止執(zhí)行,而是可以進入其他的邏輯。

創(chuàng)新互聯(lián)建站成立于2013年,我們提供高端成都網(wǎng)站建設、網(wǎng)站制作、成都網(wǎng)站設計、網(wǎng)站定制、全網(wǎng)營銷推廣小程序開發(fā)、微信公眾號開發(fā)、seo優(yōu)化排名服務,提供專業(yè)營銷思路、內(nèi)容策劃、視覺設計、程序開發(fā)來完成項目落地,為成都房屋鑒定企業(yè)提供源源不斷的流量和訂單咨詢。

在 Go 1.18 中,為 sync.Mutex 新增了一個新的方法 TryLock(),它是一種非阻塞模式的取鎖操作。當調(diào)用 TryLock() 時,該函數(shù)僅簡單地返回 true 或者 false,代表是否加鎖成功。

有了 TryLock 的存在,我們就可以由這樣的代碼:

 m.Lock()
// 阻塞等待加鎖成功后的邏輯

轉(zhuǎn)變成這樣的邏輯

 if m.TryLock(){
// 加鎖成功的邏輯
}else {
// 加鎖失敗的邏輯
}

TryLock 實現(xiàn)

在Go精妙的互斥鎖設計一文中,我們詳細分析過互斥鎖的設計,其代碼輕量簡潔,通過巧妙的位運算,僅僅采用 state 一個字段就實現(xiàn)了四個字段的效果,非常之精彩,建議感興趣的讀者一讀。

而 TryLock() 的實現(xiàn)更加簡單。

func (m *Mutex) TryLock() bool {
old := m.state
if old&(mutexLocked|mutexStarving) != 0 {
return false
}

// There may be a goroutine waiting for the mutex, but we are
// running now and can try to grab the mutex before that
// goroutine wakes up.
if !atomic.CompareAndSwapInt32(&m.state, old, old|mutexLocked) {
return false
}

if race.Enabled {
race.Acquire(unsafe.Pointer(m))
}
return true
}

當鎖被其他 goroutine 占有,或者當前鎖正處于饑餓模式,它將立即返回 false。

func (m *Mutex) Lock() {
// Fast path: grab unlocked mutex.
if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) {
if race.Enabled {
race.Acquire(unsafe.Pointer(m))
}
return
}
// Slow path (outlined so that the fast path can be inlined)
m.lockSlow()
}

而當鎖可用時,TryLock() 會采用與 Lock() 方法一樣的方式去嘗試獲取鎖。但在獲取失敗時,與 Lock() 將不一樣,它不會自旋或者阻塞。這是一個完全的非阻塞獲取方式。

應用場景

正如 TryLock() 方法的注釋一樣,它的應用場景并不常見,并且也不被鼓勵使用。

// Note that while correct uses of TryLock do exist, they are rare,
// and use of TryLock is often a sign of a deeper problem
// in a particular use of mutexes.

在當前 Go1.18 標準庫源碼中,與 Lock() 方法被大量內(nèi)部使用而截然不同的是,并沒有找到一處使用 TryLock() 的地方,僅僅在測試文件 mutex_test.go 中,有找到該方法的新增測試用例。

這里貼一個 TryLock 的使用場景討論:https://stackoverflow.com/questions/41788074/use-case-for-lock-trylock

另外,在開源社區(qū)已經(jīng)有不少 Go 的 TryLock 實現(xiàn)庫。它們基于 sync.Mutex 通過 CAS 操作和 unsafe 指針實現(xiàn) ;或者利用 channel 實現(xiàn)。

但是這些庫都不能競態(tài)檢測。因此,官方支持實現(xiàn) TryLock 是必要的,避免 TryLock 被濫用。且由于可以集成競態(tài)檢測,相較于三方庫實現(xiàn),有利于開發(fā)者發(fā)現(xiàn)問題。

總結

從 2012 年開始,實際上很早就有關于 Go 增加 TryLock 的 issue 討論,但是直到 Go 1.18 才被增加。這其中很大一部分原因是,并沒有合理的案例值得添加 TryLock。

Go Team 的負責人 rsc 之前提出的反對意見:TryLock 會鼓勵開發(fā)者對鎖進行不精確的思考,并最終導致競態(tài)問題。

另外,Go 1.18 除了為互斥鎖 sync.Mutex 新增了 TryLoc() 方法外,也為讀寫鎖 sync.RWMutex 新增了相應的 TryRLock() 和 TryLock() 方法。

正如新增的這三個方法的注釋,雖然使用它們的情況存在,但很少見,使用需謹慎。


本文名稱:一篇學會Go的TryLock實現(xiàn)
轉(zhuǎn)載來源:http://www.dlmjj.cn/article/ccessis.html