互斥锁、自旋锁和自适应自旋锁
互斥鎖:
從 實(shí)現(xiàn)原理上來(lái)講,Mutex屬于sleep-waiting類型的鎖。例如在一個(gè)雙核的機(jī)器上有兩個(gè)線程(線程A和線程B),它們分別運(yùn)行在Core0和 Core1上。假設(shè)線程A想要通過(guò)pthread_mutex_lock操作去得到一個(gè)臨界區(qū)的鎖,而此時(shí)這個(gè)鎖正被線程B所持有,那么線程A就會(huì)被阻塞 (blocking),Core0 會(huì)在此時(shí)進(jìn)行上下文切換(Context Switch)將線程A置于等待隊(duì)列中,此時(shí)Core0就可以運(yùn)行其他的任務(wù)(例如另一個(gè)線程C)而不必進(jìn)行忙等待。而Spin lock則不然,它屬于busy-waiting類型的鎖,如果線程A是使用pthread_spin_lock操作去請(qǐng)求鎖,那么線程A就會(huì)一直在 Core0上進(jìn)行忙等待并不停的進(jìn)行鎖請(qǐng)求,直到得到這個(gè)鎖為止。
適用場(chǎng)景
(1) 如果是多核處理器,如果預(yù)計(jì)線程等待鎖的時(shí)間較長(zhǎng),至少比兩次線程上下文切換的時(shí)間要長(zhǎng),建議使用互斥量。
(2) 如果是單核處理器,一般建議不要使用自旋鎖。因?yàn)?#xff0c;在同一時(shí)間只有一個(gè)線程是處在運(yùn)行狀態(tài),那如果運(yùn)行線程發(fā)現(xiàn)無(wú)法獲取鎖,只能等待解鎖,但因?yàn)樽陨聿粧炱?#xff0c;所以那個(gè)獲取到鎖的線程沒(méi)有辦法進(jìn)入運(yùn)行狀態(tài),只能等到運(yùn)行線程把操作系統(tǒng)分給它的時(shí)間片用完,才能有機(jī)會(huì)被調(diào)度。這種情況下使用自旋鎖的代價(jià)很高。
自旋鎖
自旋鎖與互斥鎖有點(diǎn)類似,只是自旋鎖不會(huì)引起調(diào)用者立即睡眠,如果自旋鎖已經(jīng)被別的執(zhí)行單元保持,調(diào)用者不放棄處理器的執(zhí)行時(shí)間, 進(jìn)行忙循環(huán)(自旋), 看是否該自旋鎖的保持者已經(jīng)釋放了鎖,”自旋”一詞就是因此而得名。(JDK1.6以后默認(rèn)開(kāi)啟了自旋鎖) 自旋的次數(shù)默認(rèn)是10次。
有些不足之處:
1、自旋鎖一直占用CPU,他在未獲得鎖的情況下,一直運(yùn)行--自旋,所以占用著CPU,如果不能在很短的時(shí) 間內(nèi)獲得鎖,這無(wú)疑會(huì)使CPU效率降低。
2、在用自旋鎖時(shí)有可能造成死鎖,當(dāng)遞歸調(diào)用時(shí)有可能造成死鎖,調(diào)用有些其他函數(shù)也可能造成死鎖,如 copy_to_user()、copy_from_user()、kmalloc()等。
因此我們要慎重使用自旋鎖,自旋鎖只有在內(nèi)核可搶占式或SMP的情況下才真正需要,在單CPU且不可搶占式的內(nèi)核下,自旋鎖的操作為空操作。自旋鎖適用于鎖使用者保持鎖時(shí)間比較短的情況下。
適用場(chǎng)景
如果是多核處理器,如果預(yù)計(jì)線程等待鎖的時(shí)間很短,短到比線程兩次上下文切換時(shí)間要少的情況下,使用自旋鎖是劃算的。
自適應(yīng)的自旋鎖
JDK1.6中引入了自適應(yīng)的自旋鎖。 自適應(yīng)意味著自旋的時(shí)間不再是固定的, 而是由前一次在同一個(gè)鎖上的自旋時(shí)間以及鎖擁有者的狀態(tài)來(lái)決定。如果在同一個(gè)鎖對(duì)象上, 自旋等待剛好成功獲得鎖, 并且在持有鎖的線程在運(yùn)行中, 那么虛擬機(jī)就會(huì)認(rèn)為這次自旋也是很有可能獲得鎖, 進(jìn)而它將允許自旋等待相對(duì)更長(zhǎng)的時(shí)間。
文章轉(zhuǎn)自:https://blog.csdn.net/jfkidear/article/details/53031828
總結(jié)
以上是生活随笔為你收集整理的互斥锁、自旋锁和自适应自旋锁的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2021垂直类电商私域化洞察报告
- 下一篇: 线程间通信及虚假唤醒