鎖機制(lock) 是多線程編程中最經常使用的同步機制,用來對多線程間共享的臨界區(Critical Section) 進行保護。編程
Pthreads提供了多種鎖機制,常見的有:
1) Mutex(互斥量):pthread_mutex_***
2) Spin lock(自旋鎖):pthread_spin_***
3) Condition Variable(條件變量):pthread_con_***
4) Read/Write lock(讀寫鎖):pthread_rwlock_***多線程
在多線程編中,根據應用場合的不一樣,選擇合適的鎖來進行同步,對多線程程序的性能影響很是大. 本文主要對 pthread_mutex 和 pthread_spinlock 兩種鎖制機進行比較,並討論其適用的場合.函數
Mutex屬於sleep-waiting類型的鎖. 從 2.6.x 系列穩定版內核開始, Linux 的 mutex 都是 futex (Fast-Usermode-muTEX)鎖.
futex(快速用戶區互斥的簡稱)是一個在Linux上實現鎖定和構建高級抽象鎖如信號量和POSIX互斥的基本工具。它們第一次出如今內核開發的2.5.7版;其語義在2.5.40固定下來,而後在2.6.x系列穩定版內核中出現。
Futex 是由Hubertus Franke(IBM Thomas J. Watson 研究中心), Matthew Kirkwood,Ingo Molnar(Red Hat)和 Rusty Russell(IBM Linux 技術中心)等人建立的。
Futex 是由用戶空間的一個對齊的整型變量和附在其上的內核空間等待隊列構成. 多進程或多線程絕大多數狀況下對位於用戶空間的futex 的整型變量進行操做(彙編語言調用CPU提供的原子操做指令來增長或減小),而其它狀況下,則須要經過代價較大的系統調用來對位於內核空間的等待隊列進行操做(如喚醒等待的進程/線程,或 將當前進程/線程放入等待隊列). 除了多個線程同時競爭鎖的少數狀況外,基於 futex 的 lock 操做是不須要進行代價昂貴的系統調用操做的.
.
這種機制的核心思想是經過將大多數狀況下非同時競爭 lock 的操做放到在用戶空間來執行,而不是代價昂貴的內核系統調用方式來執行,從而提升了效率.工具
Pthreads提供的Mutex鎖操做相關的API主要有:
一、 pthread_mutex_lock (pthread_mutex_t *mutex);
二、 pthread_mutex_trylock (pthread_mutex_t *mutex);
三、 pthread_mutex_unlock (pthread_mutex_t *mutex);性能
由於源代碼比較長,這裏不作摘錄,你們能夠參考:
glibc-2.12.2/nptl/pthread_mutex_lock.cspa
spinlock,也稱自旋鎖,是屬於busy-waiting類型的鎖.在多處理器環境中, 自旋鎖最多隻能被一個可執行線程持有。若是一個可執行線程試圖得到一個被爭用(已經被持有的)自旋鎖,那麼該線程就會一直進行忙等待,自旋,也就是空轉,等待鎖從新可用。若是鎖未被爭用,請求鎖的執行線程便馬上獲得它,繼續執行。線程
一個被爭用的自旋鎖使得請求它的線程在等待鎖從新可用時自旋,特別的浪費CPU時間,因此自旋鎖不該該被長時間的持有。實際上,這就是自旋鎖的設計初衷,在短期內進行輕量級加鎖。設計
Kernel中的自旋鎖不可以在可以致使睡眠的環境中使用。舉個例子,一個線程A得到了自旋鎖L;這個時候,發生了中斷,在對應的中斷處理函數B中,也嘗試得到自旋鎖L,就會中斷處理程序進行自旋。可是原先鎖的持有者只有在中斷處理程序結束後,採用機會釋放自旋鎖,從而致使死鎖。
因爲涉及到多個處理器環境下,spin lock的效率很是重要。由於在等待spin lock的過程,處理器只是不停的循環檢查,並不執行其餘指令。但即便這樣, 通常來講,spinlock的開銷仍是比進程調度(context switch)少得多。這就是spin lock 被普遍應用在多處理器環境的緣由隊列
Pthreads提供的與Spin Lock鎖操做相關的API主要有:
pthread_spin_lock (pthread_spinlock_t *lock);
pthread_spin_trylock (pthread_spinlock_t *lock);
pthread_spin_unlock (pthread_spinlock_t *lock);進程