日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

自旋鎖:如果內核配置為SMP系統,自旋鎖就按SMP系統上的要求來實現真正的自旋等待,但是對于UP系統,自旋鎖僅做搶占和中斷操作,沒有實現真正的“自旋”。如果配置了CONFIG_DEBUG_SPINLOCK,那么自旋鎖按照SMP系統來編譯。

但是為什么在UP系統中不需要真正的“帶有自旋的”自旋鎖呢?其實在理解了自旋鎖的概念和由來,這個問題就迎刃而解了。所以我重新查找了關于自旋鎖的資料,認真研究了自旋鎖的實現和相關內容。

一、自旋鎖spinlock的由來

眾所周知,自旋鎖最初就是為了SMP系統設計的,實現在多處理器情況下保護臨界區。所以在SMP系統中,自旋鎖的實現是完整的本來面目。但是對于UP系統,自旋鎖可以說是SMP版本的閹割版。因為只有在SMP系統中的自旋鎖才需要真正“自旋”。

二、自旋鎖的目的

自旋鎖的實現是為了保護一段短小的臨界區操作代碼,保證這個臨界區的操作是原子的,從而避免并發的競爭冒險。在linux內核中,自旋鎖通常用于包含內核數據結構的操作,你可以看到在許多內核數據結構中都嵌入有spinlock,這些大部分就是用于保證它自身被操作的原子性,在操作這樣的結構體時都經歷這樣的過程:上鎖-操作-解鎖。

如果內核控制路徑發現自旋鎖“開著”(可以獲取),就獲取鎖并繼續自己的執行。相反,如果內核控制路徑發現鎖由運行在另一個CPU上的內核控制路徑“鎖著”,就在原地“旋轉”,反復執行一條緊湊的循環檢測指令,直到鎖被釋放。 自旋鎖是循環檢測“忙等”,即等待時內核無事可做(除了浪費時間),進程在CPU上保持運行,所以它保護的臨界區必須小,且操作過程必須短。不過,自旋鎖通常非常方便,因為很多內核資源只鎖1毫秒的時間片段,所以等待自旋鎖的釋放不會消耗太多CPU的時間。

三、自旋鎖需要做的工作

從保證臨界區訪問原子性的目的來考慮,自旋鎖應該阻止在代碼運行過程中出現的任何并發干擾。這些“干擾”包括:

1、中斷,包括硬件中斷和軟件中斷(僅在中斷代碼可能訪問臨界區時需要)

這種干擾存在于任何系統中,一個中斷的到來導致了中斷例程的執行,如果在中斷例程中訪問了臨界區,原子性就被打破了。所以如果在某種中斷例程中存在訪問某個臨界區的代碼,那么就必須用spinlock保護。對于不同的中斷類型(硬件中斷和軟件中斷)對應于不同版本的自旋鎖實現,其中包含了中斷禁用和開啟的代碼。但是如果你保證沒有中斷代碼會訪問臨界區,那么使用不帶中斷禁用的自旋鎖API即可。

2、內核搶占(僅存在于可搶占內核中)

在2.6以后的內核中,支持內核搶占,并且是可配置的。這使UP系統和SMP類似,會出現內核態下的并發。這種情況下進入臨界區就需要避免因搶占造成的并發,所以解決的方法就是在加鎖時禁用搶占(preempt_disable(); ),在開鎖時開啟搶占(preempt_enable();注意此時會執行一次搶占調度)。

3、其他處理器對同一臨界區的訪問(僅SMP系統)

在SMP系統中,多個物理處理器同時工作,導致可能有多個進程物理上的并發。這樣就需要在內存加一個標志,每個需要進入臨界區的代碼都必須檢查這個標志,看是否有進程已經在這個臨界區中。這種情況下檢查標志的代碼也必須保證原子和快速,這就要求必須精細地實現,正常情況下每個構架都有自己的匯編實現方案,保證檢查的原子性。

有些人會以為自旋鎖的自旋檢測可以用for實現,這種想法“Too young, too simple, sometimes naive”!你可以在理論上用C去解釋,但是如果用for,起碼會有如下兩個問題:

(1)你如何保證在SMP下其他處理器不會同時訪問同一個的標志呢?(也就是標志的獨占訪問)

(2)必須保證每個處理器都不會去讀取高速緩存而是真正的內存中的標志(可以實現,編程上可以用volitale) 要根本解決這個問題,需要在芯片底層實現物理上的內存地址獨占訪問,并且在實現上使用特殊的匯編指令訪問。請看參考資料中對于自旋鎖的實現分析。以arm為例,從存在SMP的ARM構架指令集開始(V6、V7),采用LDREX和STREX指令實現真正的自旋等待。

四、自旋鎖操作組成

根據上的介紹,我們很容易知道自旋鎖的組成:

  • 中斷控制(僅在中斷代碼可能訪問臨界區時需要)
  • 搶占控制(僅存在于可搶占內核中需要)
  • 自旋鎖標志控制 (僅SMP系統需要)

中斷控制是按代碼訪問臨界區的不同而在編程時選用不同的變體,有些API中有,有些沒有。

而搶占控制和自旋鎖標志控制依據內核配置(是否支持內核搶占)和硬件平臺(是否為SMP)的不同而在編譯時確定。如果不需要,相應的控制代碼就編譯為空函數。 對于非搶占式內核,由自旋鎖所保護的每個臨界區都有禁止內核搶占的API,但是為空操作。由于UP系統不存在物理上的并行,所以可以閹割掉自旋的部分,剩下搶占和中斷操作部分即可。

到這里其實就可以解釋為什么我開始的實驗現象和預想的完全不同了:

由于UP系統(在不配置CONFIG_DEBUG_SPINLOCK的情況下),根本就沒有自旋鎖控制的部分,多次獲得自旋鎖是可能的(這種編程本來就是錯誤的,只是我想看錯誤的現象而已)。

對于其中的一點疑惑:

1、在有禁用中斷的版本中,既然已經禁用了中斷,在本處理器上就不會被打斷,禁用搶占是否多余?

(1)禁用了中斷可以避免因為中斷引起的搶占調度,但是如果在自旋鎖保護的臨界區中存在 preempt_disable();和 preempt_enable();對。這樣在preempt_enable();就會引發搶占調度。

(2)避免SMP系統中別的處理器執行調度程序使得本處理器的進程會被調度出去。?????

對于這個問題我不是很確定,還有深入研究調度系統后才會有準確的答案。

分享到:
標簽:自旋
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定