2011-07-06 47 views

回答

37

簡短的回答是,當您計劃在極短的時間間隔內保持鎖定時(例如,除了增加計數器之外什麼都不做),爭用預計很少,但操作是往往足以成爲潛在的性能瓶頸。螺旋鎖在互斥鎖上的優點是:

  1. 解鎖時,不需要檢查其他線程是否可能正在等待鎖定並喚醒它們。解鎖只是一個單一的原子寫入指令。
  2. 未能立即獲取鎖定並不會使您的線程處於睡眠狀態,因此只要它變爲可用狀態,它就可以以低得多的延遲獲取鎖定。
  3. 沒有緩存污染進入內核空間進入睡眠或喚醒其他線程的風險。

如果您考慮到好的互斥體實現可能會旋轉相當多的次數,然後再請求內核等待幫助,那麼第1點將始終保持不變,但第2點和第3點的有用性會有所降低。

現在,長回答:

你需要使用自旋鎖之前要問自己什麼是這些潛在的優勢是否超過一個罕見的,但非常現實的缺點:當持有鎖的線程被調度器中斷髮生了什麼然後才能釋放鎖定。這當然很少見,但即使鎖只是爲了一個單一的可變增量操作或其他同樣微不足道的事情,也可能發生。在這種情況下,任何其他嘗試獲取鎖的線程都將繼續旋轉,直到持有鎖的線程被調度並有機會釋放鎖。 如果嘗試獲取鎖的線程比擁有該鎖的線程具有更高的優先級,那麼這可能永遠不會發生。這可能是一個極端的例子,但即使沒有不同的優先級,在鎖擁有者重新安排之前可能會有很長的延遲,最糟糕的是,一旦這種情況開始,它可以迅速升級儘可能多的線程,所有這些都希望獲得鎖,開始旋轉,佔用更多的處理器時間,並進一步延遲可釋放鎖的線程的調度。

因此,我會小心的自旋鎖... :-)

12

自旋鎖是一個「忙等待」鎖。它的主要優點是它保持線程活動並且不會導致上下文切換,所以如果你知道你只會等待很短的時間(因爲你的關鍵操作非常快),那麼這可能會提供更好的性能比互斥。相反,如果關鍵部分需要很長時間並且需要上下文切換,則互斥體將對系統造成較少的需求。

TL; DR:這取決於。

0

自旋鎖只有在MP方面的興趣。它用於執行僞原子任務。在單處理器系統的原理如下:

  1. 鎖定調度(如果有中斷任務的交易,鎖定中斷代替)
  2. 做我的原子粘性
  3. 解鎖調度

但在MP系統中,我們沒有保證其他內核不會執行可以進入我們代碼部分的其他線程。爲了防止這種情況發生,自旋鎖已經創建,其目的是推遲其他內核的執行,以防止併發問題。臨界區變爲:

  1. 鎖定調度
  2. 自旋鎖(防止進入其他核)
  3. 我的任務
  4. SpinUnlock
  5. 任務解鎖

如果任務鎖省略,在調度期間,其他線程可以嘗試進入將在100%CPU等待下一個調度時循環的部分。如果這項任務是高優先級任務,則會產生死鎖。

7

性能提升最安全的方法是兩者的混合:自適應互斥鎖。

當您的系統有多個核心時,您需要旋轉幾千個週期才能捕獲低爭用或無爭用的最佳情況,然後推遲到完全互斥以讓其他線程產生長爭用鎖。

POSIX(PTHREAD_MUTEX_ADAPTIVE_NP)和Win32(SetCriticalSectionSpinCount)都具有自適應互斥鎖,許多平臺沒有POSIX自旋鎖API。