Linux的自旋鎖spin原始碼解析
阿新 • • 發佈:2018-12-15
1. 概述——————————————————————
在Linux中提供了一些鎖機制來避免競爭條件,最簡單的一種就是自旋鎖。引入鎖的機制,是因為單獨的原子操作不能滿足複雜的核心設計需要。
例如,當一個臨界區域要在,多個函式之間來回執行時,原子操作就顯得無能為力了。
Linux中一般可以認為有兩種鎖,一種是自旋鎖,另一種是訊號量。這兩種鎖是為了解決核心中遇到的不同問題開發的。
2.原理———————————————————————
結構體:
typedef struct spinlock { union { struct raw_spinlock rlock; //中間的DEBUG刪除了 }; } spinlock_t;
上鎖函式:
// 一般的上鎖 static inline void spin_lock(spinlock_t *lock) { raw_spin_lock(&lock->rlock); } // 通常用在程序中,用來禁止搶斷和禁止軟中斷 static inline void spin_lock_bh(spinlock_t *lock) { raw_spin_lock_bh(&lock->rlock); } // 判斷有沒有上鎖 static inline int spin_trylock(spinlock_t *lock) { return raw_spin_trylock(&lock->rlock); } // 既禁止本地中斷,又禁止核心搶佔 static inline void spin_lock_irq(spinlock_t *lock) { raw_spin_lock_irq(&lock->rlock); }
解鎖函式:
static inline void spin_unlock(spinlock_t *lock) { raw_spin_unlock(&lock->rlock); } static inline void spin_unlock_bh(spinlock_t *lock) { raw_spin_unlock_bh(&lock->rlock); } static inline void spin_unlock_irq(spinlock_t *lock) { raw_spin_unlock_irq(&lock->rlock); } static inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) { raw_spin_unlock_irqrestore(&lock->rlock, flags); }
3.使用——————————————————————————
spinlock t lock;
spin lock init (&lock);
spin lock (&lock);
//臨界資源
spin unlock (&lock);
注意:
自旋鎖是一種忙等待
Linux中, 自旋鎖當條件不滿足時,會一直不斷地迴圈條件是否被滿足。如果滿足,就解鎖,繼續執行下面的程式碼。這種忙等待機制是否對系統的效能有所影響呢?答案是肯定的。核心這樣設計自旋鎖確定對系統的效能,有所影響,所以在實際程式設計中,程式設計師應該注意自旋鎖不應該長時間地持有,它 "是一種適合短時間鎖定的輕量級的加鎖機制。
自旋鎖不能遞迴使用(即已經拿到鎖的執行緒,不應該再等待拿到的那個鎖)
這是因為, 自旋鎖被設計成在不同執行緒或者函式之間同步。如果一個執行緒在已經持有自旋鎖時,其處於忙等待狀態,則已經沒有機會釋放自,己持有的鎖了。如果這時再呼叫自身,則自旋鎖永遠沒有執行的機會了。所以類似下面的遞迴形式是不能使用自旋鎖的。