1. 程式人生 > >【深入理解Linux核心】自旋鎖

【深入理解Linux核心】自旋鎖

一. 訊號量

訊號量結構:

  • 一個整數變數
  • 一個等待程序的連結串列
  • 兩個原子方法:down() 和 up()

每個要保護的資料結構都有它自己的訊號量,初始值為1.

當核心控制路徑希望訪問這個資料結構是,在這個訊號量上執行down(),對訊號量的值-1。若當前訊號量的值非負,則允許訪問這個資料結構。否則,把執行核心控制路徑的程序新增到這個訊號量的連結串列中並阻塞該程序。

當另一個程序在那個訊號量上執行up()時,允許訊號量連結串列上的一個程序繼續執行。

 

二. 自旋鎖

1. 為什麼引入?

在多處理器系統中,系統不允許在不同CPU上執行的核心控制路徑同時訪問某些核心資料結構。若果修改資料結構所需的時間比較短,核心必須把程序插入到訊號量連結串列,然後掛起它,這些操作很耗時,完成這些操作時,其他的核心控制路徑可能已經釋放了這個訊號量。

2. 自旋鎖

自旋鎖與訊號量十分相近,但是沒有程序連結串列:當一個程序A發現鎖被另一個程序B鎖著,A就不停的“旋轉”,執行一個緊湊的迴圈指令直到鎖開啟。

3. 自旋鎖的特點

  • 被自旋鎖保護的臨界區程式碼執行時不能進入休眠。
  • 被自旋鎖保護的臨界區程式碼執行時是不能被被其他中斷中斷。
  • 被自旋鎖保護的臨界區程式碼執行時,核心不能被搶佔。

注:現代處理器在處理自旋鎖時都會設定自旋上限時間以防死鎖. 

4. 自旋鎖在單處理器中、多處理器中的應用

自選鎖在單處理器環境下是無效的。當核心控制路徑試圖訪問一個上鎖的資料結構時,他開始無休止的迴圈。在單處理器中,核心控制路徑可能因為修改應該受保護的資料結構而沒有機會繼續執行,也沒有機會釋放這個自旋鎖。最後的結果可能是系統掛起。因此單處理器環境不需要自旋鎖。

linux上的自旋鎖有三種實現:

1. 在單cpu,不可搶佔核心中,自旋鎖為空操作。

2. 在單cpu,可搶佔核心中,自旋鎖實現為“禁止核心搶佔”,並不實現“自旋”。

3. 在多cpu,可搶佔核心中,自旋鎖實現為“禁止核心搶佔” + “自旋”。

參考:https://blog.csdn.net/zqixiao_09/article/details/79265789