LINUX內核筆記:自旋鎖


目錄
 
1、自旋鎖作用與基本使用方法?
與其他鎖一樣,自旋鎖也用於保護臨界區,但是自旋鎖主要是用於在SMP上保護臨界區。在SMP上,自旋鎖最多只能被一個可執行線程持有,如果一個線程嘗試獲得一個被爭用的自旋鎖,該線程將一直旋轉(while循環)直到鎖可用;如果鎖未被爭用,請求鎖的執行線程將立刻爭用它,並繼續執行。
 
LINUX下自旋鎖的基本使用方法:
聲明鎖:
spinlock_t lock;
 
初始化:
lock = SPIN_LOCK_UNLOCKED;
     或者
spin_lock_init(&lock);

 

 
加鎖有4個接口,3個會阻塞,1個不阻塞
spin_lock(&lock);//獲取自旋鎖
spin_lock_irq(&lock);//關中斷,獲取自旋鎖,不建議使用
spin_lock_irqsave(&lock, flags);//關中斷,保存中斷狀態,獲取自旋鎖
spin_trylock(&lock);//與spin_lock一樣,但是獲取不到的時候不阻塞,返回非0
 
對應的解鎖接口有3個
spin_unlock(&lock);//spin_lock和spin_trylock都用該接口解鎖
spin_unlock_irq(&lock);//不建議使用
spin_unlock_irqrestore(&lock, flags);
 
另外還提供了一個獲取鎖狀態的接口:
spin_is_locked(&lock);//如果指定的鎖被獲取,返回非0,否則,返回0
 
2、在SMP和UP上的不同表現?
對於SMP,自旋鎖將在禁止搶占后,while循環自旋直到鎖可用;
對於UP,自旋鎖的行為有點不一樣,具體表現為:
  • 內核不支持搶占,則spin_lock是個空函數,spin_unlock也是空函數;
  • 內核支持搶占,則spin_lock關搶占,spin_unlock開搶占。
要分析SMP和UP的區別,還得先理解UP下內核支持搶占與否的區分。
在不支持搶占的時候,內核調度時機為:
  • 內核代碼一直要執行到完成(返回用戶空間);
  • 阻塞或主動調用schedule();
支持內核搶占的內核,則在以下情況會發生搶占:
  • 從中斷處理程序回到內核空間且內核具有搶占性時;
  • 當內核代碼再一次具有可搶占性時;(如時鍾中斷,發現進程時間片已經用完,則發生進程搶占)
  • 內核顯式調用schedule();
  • 內核中的任務阻塞(同樣導致schedule());
從以上區別可以看出,若是內核不支持搶占,只要臨界區的代碼不阻塞,就能保證原子性,所以spin_lock/spin_unlock是空函數。
而對於支持搶占的內核, spin_lock/spin_unlock自然只需要關閉/恢復搶占功能即可。
 
 
3、自旋鎖與上下文
由於自旋鎖不睡眠,既可以用於進程上下文,也可用於非進程上下文,這是它與信號量相比的一個優勢。
正常來講,如果自旋鎖都是在進程上下文中使用,則建議使用spin_lock/spin_unlock。
若在中斷處理例程中也要使用自旋鎖,則所有爭用同一個鎖的地方應使用spin_lock_irqsave/spin_unlock_irqrestore。
若沒有在中斷而在下半部使用自旋鎖,則所有急用同一個鎖的地方可以使用spin_lock_bh/spin_unlock_bh,這對函數平時用得比較少。
注:自旋鎖用在中斷例程中,若是進程上下文中的內核代碼使用spin_lock,則在臨界區,可能發生中斷 ,要么原子性被破壞(UP),要么造成死鎖(SMP).
 
4、使用spin_lock()后為什么不能睡眠?
在UP下,正如前面所說,原子性得不到保證。
而在SMP下,則可能發生死鎖:
假設有3個進程A,B,C,2個CPU稱CPU0,CPU1.
CPU0上A進程獲取自旋鎖進入睡眠,調度了B進程,B進程將自旋; 
CPU1上調度了C進程也將自旋。
B等着A釋放鎖,A等着B釋放CPU,自旋后的CPU不能發生調度,CPU0和CPU1將一直自旋下去,形成了死鎖。
 
 
5、強調:鎖什么?
使用鎖的時候一定要對症下葯,明確保護的是數據而不是代碼,這是使用鎖的正確思考方式。經常看別人代碼的人應該會有所體會,針對代碼加鎖常常使代碼難以理解,特別是復雜的程序,往往加鎖沒做好,引起競爭條件。
不防在使用鎖的時候先思考一下自己要保護什么,然后給對應的鎖取跟數據相關的名稱。比如"int foo;spinlock_t foo_lock;"表示foo由foo_lock加鎖;
 
6、參考
《Linux內核設計與實現》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM