spin_lock & mutex_lock的區別?

本文由該問題引入到內核鎖的討論,歸納如下

爲什麼需要內核鎖?
多核處理器下,會存在多個進程處於內核態的情況,而在內核態下,進程是可以訪問所有內核數據的,因此要對共享數據進行保護,即互斥處理

有哪些內核鎖機制?
(1)原子操作
atomic_t數據類型,atomic_inc(atomic_t *v)將v加1
原子操作比普通操作效率要低,因此必要時才使用,且不能與普通操作混合使用
如果是單核處理器,則原子操作與普通操作相同
(2)自旋鎖
spinlock_t數據類型,spin_lock(&lock)和spin_unlock(&lock)是加鎖和解鎖
等待解鎖的進程將反覆檢查鎖是否釋放,而不會進入睡眠狀態(忙等待),所以常用於短期保護某段代碼
同時,持有自旋鎖的進程也不允許睡眠,不然會造成死鎖——因爲睡眠可能造成持有鎖的進程被重新調度,而再次申請自己已持有的鎖
如果是單核處理器,則自旋鎖定義爲空操作,因爲簡單的關閉中斷即可實現互斥
(3)信號量與互斥量
struct semaphore數據類型,down(struct semaphore * sem)和up(struct semaphore * sem)是佔用和釋放
struct mutex數據類型,mutex_lock(struct mutex *lock)和mutex_unlock(struct mutex *lock)是加鎖和解鎖
競爭信號量與互斥量時需要進行進程睡眠和喚醒,代價較高,所以不適於短期代碼保護,適用於保護較長的臨界區
互斥量與信號量的區別?(轉載但找不到原文出處)
(1)互斥量用於線程的互斥,信號線用於線程的同步
這是互斥量和信號量的根本區別,也就是互斥和同步之間的區別
互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的
同步:是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源
(2)互斥量值只能爲0/1,信號量值可以爲非負整數
也就是說,一個互斥量只能用於一個資源的互斥訪問,它不能實現多個資源的多線程互斥問題。信號量可以實現多個同類資源的多線程互斥和同步。當信號量爲單值信號量是,也可以完成一個資源的互斥訪問
(3)互斥量的加鎖和解鎖必須由同一線程分別對應使用,信號量可以由一個線程釋放,另一個線程得到
 
 
 
 
 

[轉]mutex和spin lock的區別

mutex和spin lock的區別和應用(sleep-waiting和busy-waiting的區別)2011-10-19 11:43

信號量mutex是sleep-waiting。 就是說當沒有獲得mutex時,會有上下文切換,將自己、加到忙等待隊列中,直到另外一個線程釋放mutex並喚醒它,而這時CPU是空閒的,可以調度別的任務處理。

而自旋鎖spin lock是busy-waiting。就是說當沒有可用的鎖時,就一直忙等待並不停的進行鎖請求,直到得到這個鎖爲止。這個過程中cpu始終處於忙狀態,不能做別的任務。

例如在一個雙核的機器上有兩個線程(線程A和線程B),它們分別運行在Core0 和Core1上。 用spin-lock,coer0上的線程就會始終佔用CPU。
另外一個值得注意的細節是spin lock耗費了更多的user time。這就是因爲兩個線程分別運行在兩個核上,大部分時間只有一個線程能拿到鎖,所以另一個線程就一直在它運行的core上進行忙等待,CPU佔用率一直是100%;而mutex則不同,當對鎖的請求失敗後上下文切換就會發生,這樣就能空出一個核來進行別的運算任務了。(其實這種上下文切換對已經拿着鎖的那個線程性能也是有影響的,因爲當該線程釋放該鎖時它需要通知操作系統去喚醒那些被阻塞的線程,這也是額外的開銷)

總結
(1)Mutex適合對鎖操作非常頻繁的場景,並且具有更好的適應性。儘管相比spin lock它會花費更多的開銷(主要是上下文切換),但是它能適合實際開發中複雜的應用場景,在保證一定性能的前提下提供更大的靈活度。

(2)spin lock的lock/unlock性能更好(花費更少的cpu指令),但是它只適應用於臨界區運行時間很短的場景。而在實際軟件開發中,除非程序員對自己的程序的鎖操作行爲非常的瞭解,否則使用spin lock不是一個好主意(通常一個多線程程序中對鎖的操作有數以萬次,如果失敗的鎖操作(contended lock requests)過多的話就會浪費很多的時間進行空等待)。

(3)更保險的方法或許是先(保守的)使用 Mutex,然後如果對性能還有進一步的需求,可以嘗試使用spin lock進行調優。畢竟我們的程序不像Linux kernel那樣對性能需求那麼高(Linux Kernel最常用的鎖操作是spin lock和rw lock)。

轉自:http://blog.csdn.net/wilsonboliu/article/details/19190861

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