1. 程式人生 > >使用者態自旋鎖、讀寫自旋鎖及互斥鎖

使用者態自旋鎖、讀寫自旋鎖及互斥鎖

1、自旋鎖

自旋鎖最多可能被一個可執行執行緒所持有。一個被徵用的自旋鎖使得請求它的執行緒在等待鎖重新可用時自旋(特別浪費處理器時間)。所以自旋鎖不應該被長時間持有。

自旋鎖是不可遞迴的!

1)自旋鎖相關函式

使用者態的自旋鎖相關函式包含在標頭檔案<pthread.h>中

相關函式:

int pthread_spin_destroy(pthread_spinlock_t *lock);

銷燬自旋鎖lock,並且回收被鎖lock使用的任何資源。

int pthread_spin_init(pthread_spinlock_t *lock, int pshared);

分配使用自旋鎖lock所需要的資源,並且初始化鎖lock為未鎖狀態。

int pthread_spin_lock(pthread_spinlock_t *lock);

鎖住自旋鎖lock。當鎖沒有被某個執行緒持有時,呼叫的執行緒將獲得鎖,否則執行緒將不斷自旋,知道鎖可用。

int pthread_spin_trylock(pthread_spinlock_t *lock);

如果鎖沒有被某個執行緒持有,自旋鎖lock將被鎖住,否則將會失敗。

int pthread_spin_unlock(pthread_spinlock_t *lock);

釋放被鎖住的自旋鎖lock。

(2)基本使用形式

pthread_spin_init(&lock, 0);

pthread_spin_lock(&lock);

/*臨界區資源*/

pthread_spin_unlock(&lock);

pthread_spin_destroy(&lock);

真正需要保護的是資料而不是程式碼,採用特定的鎖保護自己的共享資料。

2、讀-寫自旋鎖

有時,鎖的用途可以明確分為讀取和寫入兩個場景。對一個連結串列可能既要更新又要檢索。當更新(寫入)連寶石,不能有其他程式碼併發地寫或者讀連結串列,寫操作要求完全的護持。另一方面,當對其檢索(讀取)連結串列時,只要求其他程式不對連結串列進行寫操作就行了,可以有多個併發的讀操作。類似於這種情況,就可以通過讀-寫鎖進型保護。

這種鎖的機制照顧寫要多一點,因此,非常適用於讀操作遠多於寫操作的場景,能提高效率。

(1)-寫鎖相關函式

使用者態的讀-寫鎖相關函式包含在標頭檔案<pthread.h>中。

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,

constpthread_rwlockattr_t *restrict attr);//初始化鎖

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);//加讀鎖

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);//加寫鎖

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);//解鎖

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);//銷燬鎖

讀-寫自旋鎖的基本使用形式跟自旋鎖差不多。

3、互斥鎖

互斥鎖說白了就是一種互斥的排他鎖-——好比允許睡眠的自旋鎖

(1)互斥鎖相關的函式

使用者態的互斥鎖相關函式包含在標頭檔案<pthread.h>中。

int pthread_mutex_init(pthread_mutex_t *restrict mutex,

constpthread_mutexattr_t *restrict attr);//初始化鎖

int pthread_mutex_lock(pthread_mutex_t *mutex);//加鎖

int pthread_mutex_unlock(pthread_mutex_t *mutex);//解鎖

int pthread_mutex_destroy(pthread_mutex_t *mutex);//銷燬鎖

(2)基本使用形式

pthread_mutex_init(&mutex);

pthread_mutex_lock(&mutex);//加鎖

/*臨界區*/

pthread_mutex_unlock(&mutex);//解鎖

自旋鎖與互斥鎖使用對比

需求

建議的加鎖方法

低開銷加鎖

優先使用自旋鎖

短期鎖定

優先使用自旋鎖

長期加鎖

優先使用互斥鎖

持有鎖需要睡眠

使用互斥鎖