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