最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

帶你走進(jìn)Linux內(nèi)核源碼中最常見的數(shù)據(jù)結(jié)構(gòu)之【mutex】

2022-10-11 15:16 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

1 定義

互斥鎖(英語:Mutual exclusion,縮寫 Mutex)是一種用于多線程編程中,防止兩條線程同時(shí)對(duì)同一公共資源(比如全域變量)進(jìn)行讀寫的機(jī)制。

該目的通過將代碼切片成一個(gè)一個(gè)的**臨界區(qū)域(critical section)**達(dá)成。臨界區(qū)域指的是一塊對(duì)公共資源進(jìn)行存取的代碼,并非一種機(jī)制或是算法。一個(gè)程序、進(jìn)程、線程可以擁有多個(gè)臨界區(qū)域,但是并不一定會(huì)應(yīng)用互斥鎖。

例如:一段代碼(甲)正在分步修改一塊數(shù)據(jù)。這時(shí),另一條線程(乙)由于一些原因被喚醒。如果乙此時(shí)去讀取甲正在修改的數(shù)據(jù),而甲碰巧還沒有完成整個(gè)修改過程,這個(gè)時(shí)候這塊數(shù)據(jù)的狀態(tài)就處在極大的不確定狀態(tài)中,讀取到的數(shù)據(jù)當(dāng)然也是有問題的。更嚴(yán)重的情況是乙也往這塊地方寫數(shù)據(jù),這樣的一來,后果將變得不可收拾。因此,多個(gè)線程間共享的數(shù)據(jù)必須被保護(hù)。達(dá)到這個(gè)目的的方法,就是確保同一時(shí)間只有一個(gè)臨界區(qū)域處于運(yùn)行狀態(tài),而其他的臨界區(qū)域,無論是讀是寫,都必須被掛起并且不能獲得運(yùn)行機(jī)會(huì)。

互斥鎖實(shí)現(xiàn)多線程同步的核心思想是:有線程訪問進(jìn)程空間中的公共資源時(shí),該線程執(zhí)行“加鎖”操作(將資源“鎖”起來),阻止其它線程訪問。訪問完成后,該線程負(fù)責(zé)完成“解鎖”操作,將資源讓給其它線程。當(dāng)有多個(gè)線程想訪問資源時(shí),誰最先完成“加鎖”操作,誰就最先訪問資源。

當(dāng)有多個(gè)線程想訪問“加鎖”狀態(tài)下的公共資源時(shí),它們只能等待資源“解鎖”,所有線程會(huì)排成一個(gè)等待(阻塞)隊(duì)列。資源解鎖后,操作系統(tǒng)會(huì)喚醒等待隊(duì)列中的所有線程,第一個(gè)訪問資源的線程會(huì)率先將資源“鎖”起來,其它線程則繼續(xù)等待。當(dāng)有多個(gè)線程想訪問“加鎖”狀態(tài)下的公共資源時(shí),它們只能等待資源“解鎖”,所有線程會(huì)排成一個(gè)等待(阻塞)隊(duì)列。資源解鎖后,操作系統(tǒng)會(huì)喚醒等待隊(duì)列中的所有線程,第一個(gè)訪問資源的線程會(huì)率先將資源“鎖”起來,其它線程則繼續(xù)等待。


mutex有什么缺點(diǎn)?

不同于mutex最初的設(shè)計(jì)與目的,現(xiàn)在的struct mutex是內(nèi)核中最大的鎖之一,比如在x86-64上,它差不多有32bytes的大小,而struct samaphore是24bytes,rw_semaphore為40bytes,更大的數(shù)據(jù)結(jié)構(gòu)意味著占用更多的CPU緩存和更多的內(nèi)存占用。


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ? ?

什么時(shí)候應(yīng)該使用mutex?

除非mutex的嚴(yán)格語義要求不合適或者臨界區(qū)域阻止鎖的共享,否則相較于其他鎖原語來說更傾向于使用mutex

mutex與spinlock的區(qū)別?


spinlock是讓一個(gè)嘗試獲取它的線程在一個(gè)循環(huán)中等待的鎖,線程在等待時(shí)會(huì)一直查看鎖的狀態(tài)。而mutex是一個(gè)可以讓多個(gè)進(jìn)程輪流分享相同資源的機(jī)制 spinlock通常短時(shí)間持有,mutex可以長時(shí)間持有 spinlock任務(wù)在等待鎖釋放時(shí)不可以睡眠,mutex可以 看到一個(gè)非常有意思的解釋:

spinlock就像是坐在車后座的熊孩子,一直問”到了嗎?到了嗎?到了嗎?…“

mutex就像一個(gè)司機(jī)返回的信號(hào),說”我們到了!“

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

看一下Linux kernel-5.8是如何實(shí)現(xiàn)mutex的2 實(shí)現(xiàn)

可以看到,mutex使用了原子變量owner來追蹤鎖的狀態(tài),owner實(shí)際上是指向當(dāng)前mutex鎖擁有者的struct task_struct *指針,所以當(dāng)鎖沒有被持有時(shí),owner為NULL。

上鎖

當(dāng)要獲取mutex時(shí),通常有三種路徑方式

fastpath:通過 cmpxchg() 當(dāng)前任務(wù)與所有者來嘗試原子性的獲取鎖。 這僅適用于無競爭的情況(cmpxchg() 檢查 0UL,因此上面的所有 3 個(gè)狀態(tài)位都必須為 0)。 如果鎖被爭用,它會(huì)轉(zhuǎn)到下一個(gè)可能的路徑。 midpath:又名樂觀旋轉(zhuǎn)(optimistic spinning)—在鎖的持有者正在運(yùn)行并且沒有其他具有更高優(yōu)先級(jí)(need_resched)的任務(wù)準(zhǔn)備運(yùn)行時(shí),通過旋轉(zhuǎn)來獲取鎖。 理由是如果鎖的所有者正在運(yùn)行,它很可能很快就會(huì)釋放鎖。 mutex spinner使用 MCS 鎖排隊(duì),因此只有一個(gè)spinner可以競爭mutex。 MCS 鎖(由 Mellor-Crummey 和 Scott 提出)是一個(gè)簡單的自旋鎖,具有公平的理想屬性,每個(gè) cpu 都試圖獲取在本地變量上旋轉(zhuǎn)的鎖,排隊(duì)采用的是鏈表實(shí)現(xiàn)的FIFO。 它避免了常見的test-and-set自旋鎖實(shí)現(xiàn)引起的昂貴的cacheline bouncing。類似MCS的鎖是專門為睡眠鎖的樂觀旋轉(zhuǎn)而量身定制的(畢竟如果只是短暫的自旋比休眠效率要高)。 自定義 MCS 鎖的一個(gè)重要特性是它具有額外的屬性,即當(dāng)spinner需要重新調(diào)度時(shí),它們能夠直接退出 MCS 自旋鎖隊(duì)列。 這有助于避免需要重新調(diào)度的 MCS spinner持續(xù)在mutex持有者上自旋,而僅需直接進(jìn)入慢速路徑獲取MCS鎖。 slowpath:最后的手段,如果仍然無法獲得鎖,則將任務(wù)添加到等待隊(duì)列并休眠,直到被解鎖路徑喚醒。 在正常情況下它阻塞為 TASK_UNINTERRUPTIBLE。 雖然正式的內(nèi)核互斥鎖是可休眠的鎖,但midpath路徑 (ii) 使它們更實(shí)際地成為混合類型。 通過簡單地不中斷任務(wù)并忙于等待幾個(gè)周期而不是立即休眠,此鎖的性能已被視為顯著改善了許多工作負(fù)載。 請(qǐng)注意,此技術(shù)也用于 rw 信號(hào)量。

具體代碼調(diào)用鏈很長…

嘗試上鎖

釋放鎖

跟加鎖對(duì)稱,也有fastpath, midpath, slowpath三條路徑。

判斷鎖狀態(tài)

很顯而易見,mutex持有者不為NULL即表示鎖定狀態(tài)。

3 實(shí)際案例

實(shí)驗(yàn):

輸出:

正確結(jié)果不應(yīng)該是1000000嗎?為什么會(huì)出錯(cuò)呢,我們可以從匯編角度來分析一下。

我們可以看到一個(gè)簡單的cnt++,對(duì)應(yīng)

CPU先將cnt的值讀到寄存器eax中,然后將[eax] + 1,最后將eax的值返回到cnt中,這些操作不是**原子性質(zhì)(atomic)**的,這就導(dǎo)致cnt被多個(gè)線程操作時(shí),+1過程會(huì)被打斷。

加入mutex保護(hù)臨界資源



帶你走進(jìn)Linux內(nèi)核源碼中最常見的數(shù)據(jù)結(jié)構(gòu)之【mutex】的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
湛江市| 宁德市| 宜春市| 图片| 什邡市| 彰武县| 阿鲁科尔沁旗| 永宁县| 鹤山市| 洛川县| 永福县| 启东市| 普洱| 浦县| 威宁| 灵武市| 灌云县| 瓮安县| 新安县| 榆林市| 威海市| 龙川县| 桐梓县| 和静县| 武清区| 岳西县| 东山县| 犍为县| 荔波县| 江安县| 水城县| 松滋市| 云浮市| 莱州市| 开封市| 郴州市| 孙吴县| 图们市| 齐齐哈尔市| 双峰县| 大田县|