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

一篇學(xué)會 Go 的 TryLock 實(shí)現(xiàn)

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

在并發(fā)編程中,為了避免多線程同時讀寫共享資源,我們需要互斥。Go 標(biāo)準(zhǔn)庫提供了互斥鎖 sync.Mutex ,通過加鎖 Lock() 方法和解鎖 Unlock() 方法達(dá)到對共享資源的并發(fā)控制。

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

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

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

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

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

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

TryLock 實(shí)現(xiàn)

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

而 TryLock() 的實(shí)現(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
}

當(dāng)鎖被其他 goroutine 占有,或者當(dāng)前鎖正處于饑餓模式,它將立即返回 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()
}

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

應(yīng)用場景

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

// 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.

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

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

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

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

總結(jié)

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

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

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

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

責(zé)任編輯:武曉燕 來源: Golang技術(shù)分享
相關(guān)推薦

2021-07-16 22:43:10

Go并發(fā)Golang

2021-12-04 22:05:02

Linux

2022-06-09 08:41:17

Go網(wǎng)絡(luò)庫Gnet

2024-04-02 12:36:01

2022-03-17 19:29:04

CSS切角自適應(yīng)

2024-05-10 08:15:32

go語言反射機(jī)制

2023-12-05 07:14:27

AIGo

2021-11-15 10:29:39

Go語言類型

2022-02-07 11:01:23

ZooKeeper

2022-01-02 08:43:46

Python

2021-10-26 10:40:26

代理模式虛擬

2022-06-30 22:53:18

數(shù)據(jù)結(jié)構(gòu)算法

2021-08-01 07:19:16

語言OpenrestyNginx

2021-07-02 08:51:29

源碼參數(shù)Thread

2021-09-28 08:59:30

復(fù)原IP地址

2021-10-14 10:22:19

逃逸JVM性能

2022-04-12 08:30:52

回調(diào)函數(shù)代碼調(diào)試

2021-10-27 09:59:35

存儲

2023-03-13 21:38:08

TCP數(shù)據(jù)IP地址

2023-11-01 09:07:01

Spring裝配源碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 黄视频免费观看 | 99精品国产一区二区三区 | 龙珠z国语版在线观看 | 精品在线看 | 综合五月婷 | 欧美一区二区三区在线免费观看 | 亚洲国产成人精品女人久久久 | 国产精品永久免费视频 | 国产精品久久精品 | 久热精品在线观看视频 | 黄网免费 | 久久精品女人天堂av | 亚洲精品99999 | 午夜成人在线视频 | 黄色免费观看网站 | 一区二区三区精品视频 | 色婷婷久久 | 国产欧美精品区一区二区三区 | 伊人最新网址 | 国产不卡一区 | 亚洲看片 | 亚洲一区二区三区免费在线观看 | 最近最新中文字幕 | 国产亚洲欧美日韩精品一区二区三区 | 日韩在线免费看 | 午夜精品视频 | 亚洲精品久久久久avwww潮水 | 亚洲免费观看视频 | 亚洲精品久久久蜜桃 | 国产一级淫片免费视频 | 伊人伊人伊人 | 97精品国产97久久久久久免费 | 欧美成人在线免费 | www精品| 国产精品久久久久无码av | 亚洲一区二区 | 久久久亚洲一区 | 北条麻妃99精品青青久久主播 | 精品视频www | 成av在线 | 国产精品一区二区在线 |