Linux自旋鎖

  • 自旋鎖概念

自旋鎖顧名思義首先是一把鎖,另外使用這把鎖的線程需要反覆自我循環(loop)檢測這把鎖是否可用。注意與信號量區別,信號量也是一把鎖,但是使用這把鎖的線程檢測鎖不可用時,選擇去睡眠,而不是自我循環。

自旋鎖與信號量相同點是兩者都是鎖,都具備鎖定特性,實現臨界區代碼塊的同步與互斥訪問。

  • 自旋鎖注意事項

  1. 臨界區代碼不要存在睡眠情況(主要因爲發生睡眠不可預知睡眠多長時間,另外長時間睡眠,導致即將進入臨界區其他線程,長時間得不到自旋鎖,無休止自旋,從而導致死鎖),所以臨界區調用導致睡眠函數,不能選擇自旋鎖。
  2. 保證進入臨界區的線程,不發生內核搶佔。(這一點不必擔心,持有自旋鎖情況,Linux內核不進行搶佔)
  3. 臨界區代碼,執行時間不能太長。(因爲其他線程,如果要進入話,導致自旋,過多消耗CPU資源)
  4. 選擇自旋鎖時,也要注意中斷情況(上半部分中斷(硬件中斷)和下半部分中斷(軟中斷),中斷會搶佔即中斷到來時,打斷目前臨界區代碼執行,轉往執行中斷代碼),當中斷要進入自旋鎖保護臨界區代碼時,將導致線程與中斷髮生死鎖可能。

  • 自旋鎖函數

1)自旋鎖頭文件

<linux/spinlock.h>

2)自旋鎖數據類型

spinlock_t

3)自旋鎖變量靜態(編譯時)初始化

spinlock_t lock = SPIN_LOCK_UNLOCKED;

4)自旋鎖變量動態(運行時)初始化

spinlock_t lock

spin_lock_init(&lock);

5)鎖定函數

void spin_lock(spinlock_t *lock);

void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);

void spin_lock_irq(spinlock_t *lock); 禁止(屏蔽硬件中斷)自旋鎖,針對場合4情況

void spin_lock_bh(spinlock_t *lock);禁止(屏蔽下半部分中斷)自旋鎖,針對場合4情況

6)解鎖函數

void spin_unlock(spinlock_t *lock);

void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);

void spin_unlock_irq(spinlock_t *lock);

void spin_unlock_bh(spinlock_t *lock);

  • 讀寫自旋鎖

鎖的用途可以明確地分爲讀和寫。這種自旋鎖爲讀和寫分別提供了不同的鎖。一個或多少任務可以併發地持有讀取鎖;而寫入鎖一次最多隻能被一個任務持有,而且此時不能有併發的讀操作。我們可以將讀/寫鎖分別叫做共享(併發)/排斥鎖 。

讀寫自旋鎖相關函數

1)自旋鎖頭文件

<linux/rwlock.h>

2)自旋鎖數據類型

rwlock_t

3)自旋鎖變量靜態(編譯時)初始化

rwlock_t my_rwlock = RW_LOCK_UNLOCKED; 

4)自旋鎖變量動態(運行時)初始化

rwlock_t my_rwlock;

rwlock_init(&my_rwlock);

5)讀鎖定函數

void read_lock(rwlock_t* lock);

void read_lock_irqsave(rwlock_t* lock, unsigned long flags);

void read_lock_irq(rwlock_t* lock);//禁止(屏蔽硬件中斷)自旋鎖,針對場合4情況

void read_lock_bh(rwlock_t* lock);//禁止(屏蔽下半部分中斷)自旋鎖,針對場合4情況

6)讀解鎖函數

void read_unlock(rwlock_t* lock);

void read_unlock_irqrestore(rwlock_t* lock, unsigned long flags);

void read_unlock_irq(rwlock_t* lock);

void read_unlock_bh(rwlock_t* lock);

6)寫鎖定函數

void write_lock(rwlock_t* lock);

void write_lock_irqsave(rwlock_t* lock, unsigned long flags);

void write_lock_irq(rwlock_t* lock);

void write_lock_bh(rwlock_t* lock);

void write_trylock(rwlock_t* lock);//嘗試獲得寫自旋鎖,不管是否成功,都會立即返回;

6)寫解鎖函數

void write_unlock(rwlock_t* lock);

void write_unlock_irqsave(rwlock_t* lock, unsigned long flags);

void write_unlock_irq(rwlock_t* lock);

void write_unlock_bh(rwlock_t* lock);






參考:http://blog.csdn.net/zhuriyuxiao/article/details/7641540

http://bdxnote.blog.163.com/blog/static/844423520124268101627/


發佈了34 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章