線程同步有關鎖的術語介紹

在多線程中,鎖是一種最經常使用的同步工具,下面詳細講講帶有鎖字的一些術語:數據庫

1.鎖的具體實現原理:多線程

(1).互斥鎖(Mutex)併發

用一個「互斥鎖」的對象,任一時刻,只有一個線程能訪問這個對象,也就是把代碼分紅一個個臨界區域。在Linux下僞代碼以下:
函數

pthread_mutex_t mutex;

pthread_mutex_init (&mutex, NULL); /*初始化鎖*/

pthread_mutex_lock(&mutex); /*獲取互斥鎖,也就是加鎖*/

... /*臨界區*/

pthread_mutex_unlock(&mutex); /*解鎖互斥鎖*/

如圖,中間的臨界區就實現了加鎖,每次只有一個線程才能訪問。基本上咱們線程同步用的都是互斥鎖。工具

2.自旋鎖(Spin Lock)spa

跟互斥鎖類型,都是爲了實現互斥訪問某個對象,可是互斥鎖在資源被佔用的時候會進入睡眠,而自旋鎖則會一直循環去探測可否獲取資源,在某種意義上,就是一直while循環探測。因此自旋鎖很容易就佔用cpu過多,可是不須要線程的休眠調度等,會效率比較高,適用加鎖時間很短的狀況。線程

3.讀寫鎖(RWLock)code

讀寫鎖就是一個特殊的自旋鎖,只是把須要進入臨界區的訪問者分紅讀者和寫者,寫者是排他的,可是容許多個讀者同時存在。也就是說若是沒有讀者和寫者,那麼寫者能夠馬上得到讀寫鎖,不然它必須自旋在那裏,直到沒有任何寫者或讀者。若是讀寫鎖沒有寫者,即便有其餘讀者,這個讀者也能夠當即得到該讀寫鎖,不然讀者必須自旋在那裏,直到寫者釋放該讀寫鎖。對象

互斥鎖跟自旋鎖一些優缺點:blog

Spinlock優勢:沒有昂貴的系統調用,一直處於用戶態,執行速度快。

Spinlock缺點:一直佔用cpu,並且在執行過程當中還會鎖bus總線,鎖總線時其餘處理器不能使用總線。

Mutex優勢:不會忙等,得不到鎖會sleep。

Mutex缺點:sleep時會陷入到內核態,須要昂貴的系統調用。

2.鎖的一些分類

1.遞歸鎖(Recursive Lock)和非遞歸鎖(Non-Recursive Lock)

兩個惟一的區別就是一個線程能夠屢次獲取一個遞歸鎖,而不會致使死鎖,而屢次獲取一個非遞歸鎖就會致使死鎖。以下:

mutex_init(&mutex);
void fun()
{
  lock(&mutex);
  //do something1
  fun2();
  unlock&mutex);
}

void fun2()
{
  lock(&mutex);
  //do something2
  unlock(&mutex);
}

在fun()函數加鎖調用了fun2(),而fun2()也加了鎖,若是是非遞歸鎖,那麼fun獲取了mutex,fun2再去獲取mutex,就會致使死鎖了。

2.樂觀鎖(Optimistic Lock)和悲觀鎖(Pessimistic Lock)

主要是用於關係型數據庫存儲。樂觀鎖,大可能是基於數據版本(Version)記錄機制實現,即爲數據增長一個版本標識。讀取出數據時,將此版本號一同讀出,以後更新時,對此版本號加一。之後提。優勢是對於併發的數據庫讀取,避免了長時間的加鎖開銷等待,缺點也比較明顯,可能致使不正確的數據存入數據庫。悲觀鎖就比較容易理解了,也就是在整個數據庫操做中,數據都處於鎖定狀態。也就是說在數據進行一個讀的事務中,全部對整個數據的修改都無法進行。

3.死鎖(Dead Lock)和活鎖(Live Lock)

死鎖你們應該都比較清楚,簡單地說,就是進入死等待,例如P1佔用了資源A,請求資源B,而P2佔用了資源B,請求資源A,這樣就致使雙方一直在等待。而活鎖就是資源一直輪不到本身使用,致使一直飢餓,例如若是事務T1封鎖了數據R,事務T2請求封鎖R,因而T2等待。T3也請求封鎖R,當T1釋放了R上的封鎖以後系統首先批准了T3的請求,T2仍然等待。而後T4又請求封鎖R,當T3釋放了R上的封鎖以後系統又批准了T4的請求,...,T2有可能永遠等待,這就是活鎖的情形。

主要是一些概念的介紹,具體的還須要具體去用了才能體會。

謝謝指教。

相關文章
相關標籤/搜索