spinlock和semaphore的差別和應用

轉自 http://group.ednchina.com/1036/18550.aspx 

 

 

這兩天經常有同事在問我spinlocksemaphore的相關問題,什麼時候該用spinlock?什麼時候該用semaphore?什麼時候該用spinlock_irq?什麼時候該用spinlock_irqsave?的確,對於初涉內核開發的人員來說,spinlocksemaphore的應用是一個比較大的疑問。這裏,我來談談我對這兩個概念的想法吧。

 

Spinlock的實現機制可以描述如下:CPU首先將內存總線lock住,然後檢測內存中的lock數據,如果數據爲真,那麼表示資源被人佔用,無法獲取。然後CPU會自璇檢測該lock數據,直到數據不爲真之後,lock該數據返回。在Linuxspinlock核心代碼採用彙編語言實現,可以參考__raw_spin_lock函數。在2.6.25版本之後,Linux爲了解決在多CPU平臺上的不公平競爭,引入了排隊自璇鎖的算法。

 

說道這裏,需要講一下的是,spinlockup平臺上爲空函數的說法。這個說法不是很嚴格,實際上在非強佔的up平臺上,spinlock的實現爲空函數,在可強佔的up平臺上,spinlock需要將強佔給disable掉,也就是說在spinlock的臨界區,Linux無法強佔。在多CPU平臺上,spinlock是有效的。

 

Semaphore的實現機制可以描述如下:CPU首先會檢測信號量是否可獲取,如果無法獲取該信號量,那麼就會導致一次上下文調度操作。從實現機制上來看,semaphore操作效率比較低,而spinlock的效率相對較高,但是這種效率的高低與應用相關,如果臨界區操作的時間過長,那麼採用spinlock會浪費大量的CPU時間,還不如做幾次上下文調度釋放CPU資源呢。所以,spinlock的應用有一個原則,那就是臨界區操作儘可能的短,讓CPU不要自璇太多的時間,這一點從spinlock的實現代碼上也可以看出一些端倪,Linux開發人員着這個地方花費了好多心計。

 

從上面的機制描述,我想可以總結出如下幾點:

1  不允許睡眠的上下文需要採用spinlock,可以睡眠的上下文可以採用semaphore。在中斷上下文中訪問的競爭資源一定採用spinlock

2  臨界區操作較長的應用建議採用semaphore,臨界區很短的操作建議採用spinlock

3  需要關中斷的場合需要調用spinlock_irq或者spinlock_irqsave,不明確當前中斷狀態的地方需要調用spinlock_irqsave,否則調用spinlock_irq。一個資源既在中斷上下文中訪問,又在用戶上下文中訪問,那麼需要關中斷,如果僅僅在用戶上下文中被訪問,那麼無需關中斷。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章