spin_lock、spin_lock_irq、spin_lock_irqsave區別【轉】
轉自:http://blog.csdn.net/luckywang1103/article/details/42083613
void spin_lock(spinlock_t *lock);
void spin_lock_irq(spinlock_t *lock);
void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);
1、spin_lock與spin_lock_irq區別
在Linux核心中何時使用spin_lock,何時使用spin_lock_irqsave很容易混淆。首先看一下程式碼是如何實現的。
spin_lock的呼叫關係
spin_lock
|
+ —–> raw_spin_lock
|
+——> _raw_spin_lock
|
+——–> __raw_spin_lock
- static inline void __raw_spin_lock(raw_spinlock_t *lock)
- {
- preempt_disable();
- spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
- LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
- }
spin_lock_irq的呼叫關係
spin_lock_irq
|
+——-> raw_spin_lock_irq
|
+———> _raw_spin_lock_irq
|
+————> __raw_spin_lock_irq
- static inline void __raw_spin_lock_irq(raw_spinlock_t *lock)
- {
- local_irq_disable();
- preempt_disable();
- spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
- LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
- }
可以看出來他們兩者只有一個差別:是否呼叫local_irq_disable()函式, 即是否禁止本地中斷。
在任何情況下使用spin_lock_irq都是安全的。因為它既禁止本地中斷,又禁止核心搶佔。
spin_lock比spin_lock_irq速度快,但是它並不是任何情況下都是安全的。
舉個例子:程式A中呼叫了spin_lock(&lock)然後進入臨界區,此時來了一箇中斷(interrupt),
該中斷也執行在和程式A相同的CPU上,並且在該中斷處理程式中恰巧也會spin_lock(&lock)
試圖獲取同一個鎖。由於是在同一個CPU上被中斷,程式A會被設定為TASK_INTERRUPT狀態,
中斷處理程式無法獲得鎖,會不停的忙等,由於程式A被設定為中斷狀態,schedule()程式排程就
無法再排程程式A執行,這樣就導致了死鎖!
但是如果該中斷處理程式執行在不同的CPU上就不會觸發死鎖。 因為在不同的CPU上出現中斷不會導致
程式A的狀態被設為TASK_INTERRUPT,只是換出。當中斷處理程式忙等被換出後,程式A還是有機會
獲得CPU,執行並退出臨界區。
所以在使用spin_lock時要明確知道該鎖不會在中斷處理程式中使用。
2、spin_lock_irq與spin_lock_irqsave區別
spin_lock_irqsave在進入臨界區前,儲存當前中斷暫存器flag狀態,關中斷,進入臨界區,在退出臨界區時,把儲存的中斷狀態寫回到中斷暫存器。
spin_lock_irq在進入臨界區前不儲存中斷狀態,關中斷,進入臨界區,在退出臨界區時,開中斷。
spin_lock_irqsave鎖返回時,中斷狀態不會被改變,呼叫spin_lock_irqsave前是開中斷返回就開中斷。
spin_lock_irq鎖返回時,永遠都是開中斷,即使spin_lock_irq前是關中斷
轉自:http://blog.csdn.net/zhanglei4214/article/details/6837697
http://blog.csdn.net/lbo4031/article/details/8894830
本文轉自張昺華-sky部落格園部落格,原文連結:http://www.cnblogs.com/sky-heaven/p/5310298.html,如需轉載請自行聯絡原作者
相關文章
- [轉]OOA/OOD/OOP區別OOP
- [轉] js == 與 === 的區別JS
- InnoDB和MyISAM 區別(轉)
- 轉發和重定向的區別(轉)
- 【轉】mysql 和 redis的區別MySqlRedis
- HttpRequest 和HttpWebRequest的區別(轉)HTTPWeb
- Oracle各版本區別(轉載)Oracle
- 轉:SAN和NAS的區別
- Latch和Lock的區別(轉)
- Public與Private的區別 (轉)
- editchanged 和 itemchanged 的區別(轉)
- JavaScript和Java的區別(轉)JavaScript
- (轉)CWnd與HWND的區別與轉換
- Gson轉換與JSONObject區別JSONObject
- 轉發和重定向的區別?
- CPU單核多核區別【轉載】單核
- frame和bounds的區別(轉載)
- 轉發與重定向的區別
- (轉)ORACLE 中IN和EXISTS的區別Oracle
- java bean 與 ejb的區別 (轉)JavaBean
- 轉:IDOCBAPIRFC區別和聯絡API
- 菜鳥、大牛、教主的區別(轉)、、、、
- (轉)編譯和連結的區別編譯
- 轉 shell中$(( )) 與 $( ) 還有${ }的區別
- redis、memcache、mongoDB有哪些區別(轉載)RedisMongoDB
- EMR和ERP有何區別(轉)
- Oracle與MySQL的幾點區別(轉)OracleMySql
- malloc/free 和 new /delete 的區別 (轉)delete
- su和sudo的區別與使用(轉)
- XHTML?它與 HTML的區別?如何轉換HTML
- Java中HashMap,LinkedHashMap,TreeMap的區別[轉]JavaHashMap
- 【轉】理解 CI 和 CD 之間的區別
- disconnect session和kill session的區別 轉Session
- 在Oracle中session和process的區別(轉)OracleSession
- 【轉】C#中virtual和abstract的區別C#
- 【轉】Session ID/session token 及和cookie區別SessionCookie
- [轉]聚集索引和非聚集索引的區別索引
- [轉]Apache與Tomcat 區別及聯絡ApacheTomcat