一文搞懂多線程中各個(gè)難點(diǎn)
6.3.4互斥量的解鎖
int pthread_mutex_unlock(pthread_mutex_t *mutex);
對(duì)上述所有的加鎖接口,都可使用該函數(shù)解鎖
解鎖的時(shí)候,會(huì)將互斥鎖當(dāng)中計(jì)數(shù)器的值從0變?yōu)?,表示其它線程可以獲取互斥量
6.4互斥鎖的本質(zhì)
1、在互斥鎖內(nèi)部有一個(gè)計(jì)數(shù)器,其實(shí)就是互斥量,計(jì)數(shù)器的值只能為0或者為1
2、當(dāng)線程獲取互斥鎖的時(shí)候,如果計(jì)數(shù)器當(dāng)前值為0,表示當(dāng)前線程不能獲取到互斥鎖,也就是沒有獲取到互斥鎖,就不要去訪問臨界資源
3、當(dāng)前線程獲取互斥鎖的時(shí)候,如果計(jì)數(shù)器當(dāng)前值為1,表示當(dāng)前線程可以獲取到互斥鎖,也就是意味著可以訪問臨界資源
6.5互斥鎖中的計(jì)數(shù)器如何保證了原子性?
獲取鎖資源的時(shí)候(加鎖):
1、寄存器當(dāng)中值直接賦值為0
2、將寄存器當(dāng)中的值和計(jì)數(shù)器當(dāng)中的值進(jìn)行交換
3、判斷寄存器當(dāng)中的值,得出加鎖結(jié)果
兩種情況:
例:4個(gè)線程,對(duì)同一個(gè)全局變量進(jìn)行減減操作
#include
互斥鎖是不公平的。
內(nèi)核維護(hù)等待隊(duì)列, 互斥量實(shí)現(xiàn)了大體上的公平;由于等待線程被喚醒后, 并不自動(dòng)持有互斥量, 需要和剛進(jìn)入臨界區(qū)的線程競(jìng)爭(zhēng)(搶鎖), 所以互斥量并沒有做到先來先服務(wù)。
6.7互斥鎖的類型
1、PTHREAD_MUTEX_NORMAL:最普通的一種互斥鎖。它不具備死鎖檢測(cè)功能, 如線程對(duì)自己鎖定的互斥量再次加鎖, 則會(huì)發(fā)生死鎖。
2、
PTHREAD_MUTEX_RECURSIVE_NP:支持遞歸的一種互斥鎖, 該互斥量的內(nèi)部維護(hù)有互斥鎖的所有者和一個(gè)鎖計(jì)數(shù)器。當(dāng)線程第一次取到互斥鎖時(shí), 會(huì)將鎖計(jì)數(shù)器置1, 后續(xù)同一個(gè)線程再次執(zhí)行加鎖操作時(shí), 會(huì)遞增該鎖計(jì)數(shù)器的值。解鎖則遞減該鎖計(jì)數(shù)器的值, 直到降至0, 才會(huì)真正釋放該互斥量, 此時(shí)其他線程才能獲取到該互斥量。解鎖時(shí), 如果互斥量的所有者不是調(diào)用解鎖的線程, 則會(huì)返回EPERM。
3、
PTHREAD_MUTEX_ERRORCHECK_NP:支持死鎖檢測(cè)的互斥鎖;コ饬康膬(nèi)部會(huì)記錄互斥鎖的當(dāng)前所有者的線程ID(調(diào)度域的線程ID) 。如果互斥量的持有線程再次調(diào)用加鎖操作, 則會(huì)返回EDEADLK。解鎖時(shí), 如果發(fā)現(xiàn)調(diào)用解鎖操作的線程并不是互斥鎖的持有者, 則會(huì)返回EPERM。
4、自旋鎖,自旋鎖采用了和互斥量完全不同的策略, 自旋鎖加鎖失敗, 并不會(huì)讓出CPU, 而是不停地嘗試加鎖, 直到成功為止。這種機(jī)制在臨界區(qū)非常小且對(duì)臨界區(qū)的爭(zhēng)奪并不激烈的場(chǎng)景下, 效果非常好。自旋鎖的效果好, 但是副作用也大, 如果使用不當(dāng), 自旋鎖的持有者遲遲無法釋放鎖, 那么, 自旋接近于死循環(huán), 會(huì)消耗大量的CPU資源, 造成CPU使用率飆高。因此, 使用自旋鎖時(shí), 一定要確保臨界區(qū)盡可能地小, 不要有系統(tǒng)調(diào)用, 不要調(diào)用sleep。使用strcpy/memcpy等函數(shù)也需要謹(jǐn)慎判斷操作內(nèi)存的大小, 以及是否會(huì)引起缺頁中斷。
5、PTHREAD_MUTEX_ADAPTIVE_NP:自適應(yīng)鎖,首先與自旋鎖一樣, 持續(xù)嘗試獲取, 但過了一定時(shí)間仍然不能申請(qǐng)到鎖, 就放棄嘗試, 讓出CPU并等待。PTHREAD_MUTEX_ADAPTIVE_NP類型的互斥量, 采用的就是這種機(jī)制。
6.8死鎖和活鎖
線程1已經(jīng)成功拿到了互斥量1, 正在申請(qǐng)互斥量2, 而同時(shí)在另一個(gè)CPU上,線程2已經(jīng)拿到了互斥量2, 正在申請(qǐng)互斥量1。彼此占有對(duì)方正在申請(qǐng)的互斥量,結(jié)局就是誰也沒辦法拿到想要的互斥量, 于是死鎖就發(fā)生了。
6.8.1死鎖概念
死鎖是指在一組進(jìn)程中的各個(gè)進(jìn)程均占有不會(huì)釋放的資源,但因互相申請(qǐng)被其它進(jìn)程所占有不會(huì)釋放的資源而處于一種永久等待的狀態(tài)。
6.8.2死鎖的四個(gè)必要條件
1、互斥條件:一個(gè)資源只能被一個(gè)執(zhí)行流使用
2、請(qǐng)求與保持條件:一個(gè)執(zhí)行流因請(qǐng)求資源而阻塞時(shí),對(duì)已獲得的資源不會(huì)釋放
3、不剝奪條件:一個(gè)執(zhí)行流已獲得的資源,在未使用完之前,不能強(qiáng)行剝奪
4、循環(huán)等待條件:若干執(zhí)行流之間形成一種頭尾相接的循環(huán)等待資源的關(guān)系
6.8.3避免死鎖
1、破壞死鎖的四個(gè)必要條件(實(shí)際上只能破壞條件2和4)
2、加鎖順序一致(按照先后順序申請(qǐng)互斥鎖)
3、避免未釋放鎖的情況
4、資源一次性分配
6.8.4活鎖
避免死鎖的另一種方式是嘗試一下,如果取不到鎖就返回。
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,const struct timespec *restrict abs_timeout);
這兩個(gè)函數(shù)反映了一種,不行就算了的思想。
trylock不行就回退的思想有可能會(huì)引發(fā)活鎖(live lock) 。生活中也經(jīng)常遇到兩個(gè)人迎面走來, 雙方都想給對(duì)方讓路, 但是讓的方向卻不協(xié)調(diào), 反而互相堵住的情況 ;铈i現(xiàn)象與這種場(chǎng)景有點(diǎn)類似。
線程1首先申請(qǐng)鎖mutex_a后, 之后嘗試申請(qǐng)mutex_b, 失敗以后, 釋放mutex_a進(jìn)入下一輪循環(huán), 同時(shí)線程2會(huì)因?yàn)閲L試申請(qǐng)mutex_a失敗,而釋放mutex_b, 如果兩個(gè)線程恰好一直保持這種節(jié)奏, 就可能在很長(zhǎng)的時(shí)間內(nèi)兩者都一次次地擦肩而過。當(dāng)然這畢竟不是死鎖, 終究會(huì)有一個(gè)線程同時(shí)持有兩把鎖而結(jié)束這種情況。盡管如此, 活鎖的確會(huì)降低性能。
6.8.5死鎖調(diào)試
查看多個(gè)線程堆棧:thread apply all bt
跳轉(zhuǎn)到線程中:t 線程號(hào)
查看具體的調(diào)用堆棧:f 堆棧號(hào)
直接從pid號(hào)用gdb調(diào)試:gdb attach pid
#include
在上述代碼中,一定會(huì)出現(xiàn)死鎖,線程1拿到了互斥鎖1,又再去申請(qǐng)線程2的互斥鎖2,線程2拿到了互斥鎖2又再去申請(qǐng)線程1的互斥鎖1。
開始調(diào)試:
1、找到進(jìn)程號(hào)
2、開始調(diào)試
3、查看多個(gè)線程堆棧
4、跳轉(zhuǎn)到線程中
5、查看具體調(diào)用堆棧
6、查看互斥鎖1和互斥鎖2,分別被誰拿著

發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
圖片新聞
-
馬云重返一線督戰(zhàn),阿里重啟創(chuàng)始人模式
-
機(jī)器人奧運(yùn)會(huì)戰(zhàn)報(bào):宇樹機(jī)器人摘下首金,天工Ultra搶走首位“百米飛人”
-
存儲(chǔ)圈掐架!江波龍起訴佰維,索賠121萬
-
長(zhǎng)安汽車母公司突然更名:從“中國(guó)長(zhǎng)安”到“辰致科技”
-
豆包前負(fù)責(zé)人喬木出軌BP后續(xù):均被辭退
-
字節(jié)AI Lab負(fù)責(zé)人李航卸任后返聘,Seed進(jìn)入調(diào)整期
-
員工持股爆雷?廣汽埃安緊急回應(yīng)
-
中國(guó)“智造”背后的「關(guān)鍵力量」
最新活動(dòng)更多
-
10月23日火熱報(bào)名中>> 2025是德科技創(chuàng)新技術(shù)峰會(huì)
-
10月23日立即報(bào)名>> Works With 開發(fā)者大會(huì)深圳站
-
11月7日立即參評(píng)>> 【評(píng)選】維科杯·OFweek 2025(第十屆)物聯(lián)網(wǎng)行業(yè)年度評(píng)選
-
即日-11.25立即下載>>> 費(fèi)斯托白皮書《柔性:汽車生產(chǎn)未來的關(guān)鍵》
-
11月27日立即報(bào)名>> 【工程師系列】汽車電子技術(shù)在線大會(huì)
-
11月28日立即下載>> 【白皮書】精準(zhǔn)洞察 無線掌控——283FC智能自檢萬用表
推薦專題
- 1 特斯拉工人被故障機(jī)器人打成重傷,索賠3.6億
- 2 【行業(yè)深度研究】退居幕后四年后,張一鳴終于把算法公司變成AI公司?
- 3 AI 時(shí)代,阿里云想當(dāng)“安卓” ,那誰是“蘋果”?
- 4 拐點(diǎn)已至!匯川領(lǐng)跑工控、埃斯頓份額第一、新時(shí)達(dá)海爾賦能扭虧為盈
- 5 L3自動(dòng)駕駛延期,逼出車企技術(shù)自我淘汰
- 6 隱退4年后,張一鳴久違現(xiàn)身!互聯(lián)網(wǎng)大佬正集體殺回
- 7 谷歌“香蕉”爆火啟示:國(guó)產(chǎn)垂類AI的危機(jī)還是轉(zhuǎn)機(jī)?
- 8 00后華裔女生靠?jī)刹緼I電影狂賺7.8億人民幣,AI正式進(jìn)軍好萊塢
- 9 機(jī)器人9月大事件|3家國(guó)產(chǎn)機(jī)器人沖刺IPO,行業(yè)交付與融資再創(chuàng)新高!
- 10 市值暴漲千億,這潑天富貴終于輪到百度了
- 高級(jí)軟件工程師 廣東省/深圳市
- 自動(dòng)化高級(jí)工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級(jí)銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市