自旋鎖與信號量的區別

自旋鎖最多隻能被一個可執行線程持有(讀寫自旋鎖除外)自旋鎖不會引起調用者睡眠,如果一個執行線程試圖獲得一個已經被持有的自旋鎖,那麼線程就會一直進行忙循環一直等待下去(一直佔用 CPU ),在那裏看是否該自旋鎖的保持者已經釋放了鎖, " 自旋 " 一詞就是因此而得名。

由於自旋鎖使用者一般保持鎖時間非常短,因此選擇自旋而不是睡眠是非常必要的,自旋鎖的效率遠高於互斥鎖。

信號量和讀寫信號量適合於保持時間較長的情況,它們會導致調用者睡眠,因此只能在進程上下文使用(因爲中斷的上下文不允許休眠)

自旋鎖保持期間是搶佔失效的(內核不允許被搶佔) ,而信號量和讀寫信號量保持期間是可以被搶佔的。自旋鎖只有在內核可搶佔或 SMP 的情況下才真正需要,在單 CPU 且不可搶佔的內核下,自旋鎖的所有操作都是空操作。

(問題:在單 CPU 可搶佔內核中,如果一個進程請求自旋鎖,那麼他一直佔用 CPU 循環等待自旋鎖可用,那麼原來佔用自旋鎖的進程得不到使用 CPU 的機會,怎麼釋放它自己佔用的自旋鎖呢?

回答:這種情況應該是在實際中不會發生的。因爲考慮最開始的情況,一個進程需要自旋鎖,而且這個時候自旋鎖沒有被佔用,所以他加鎖,進入臨界區。因爲這個時候內核已經被自旋鎖設置成了非搶佔式,所以正在運行的進程不會被調用處 CPU ,因此也不會再有其他的進程來請求這個已經被佔用的自旋鎖,當臨界區代碼處理完成後,釋放了自旋鎖,此時內核又被自旋鎖設置成了可搶佔模式,這個時候其他的進程可以被調度,因此可以再請求自旋鎖等操作。因此問題中的情況應該在實際中不會發生。

注意,如果在一個已經對某個自旋鎖加鎖的進程的臨界區中又申請對這個自旋鎖加鎖,則會導致進程自旋在那裏,引起死機。)

 

一個執行單元要想訪問被自旋鎖保護的共享資源,必須先得到鎖,在訪問完共享資源後,必須釋放鎖。如果在獲取自旋鎖時,沒有任何執行單元保持該鎖,那麼將立即得到鎖;如果在獲取自旋鎖時鎖已經有保持者,那麼獲取鎖操作將自旋在那裏,直到該自旋鎖的保持者釋放了鎖。

 

因爲自旋鎖在同一時刻至多被一個執行線程持有,所以一個時刻只能有一個線程位於臨界區,這就爲多處理器提供了防止併發訪問所需的保護機制,但是在單處理器上,編譯的時候不會加入自旋鎖。它僅僅被當作一個設置內核搶佔機制是否被啓用的開關 gx 自己的理解:在單內核可搶佔式內核中,對自旋鎖加鎖導致禁止搶佔,對自旋鎖解鎖導致恢復搶佔模式。

 

-------- 自旋鎖對信號量 ------------------------------------------------------

需求                                     建議的加鎖方法

低開銷加鎖                            優先使用自旋鎖

短期鎖定                             優先使用自旋鎖

長期加鎖                             優先使用信號量

中斷上下文中加鎖                   使用自旋鎖

持有鎖是需要睡眠、調度           使用信號量

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章