讀寫鎖的實現

什麼是讀寫鎖:併發

讀寫鎖實際是種特殊的旋鎖,它把對共享資源的訪問者劃分紅讀者和寫者,讀者只對共享資源進讀訪問,寫者則須要對共享資源進寫操做。這種鎖相對於旋鎖,能提併發性,由於在多處理器系統中,它容許同時有多個讀者來訪問共享資源,最可能的讀者數爲實際的邏輯CPU數。寫者是排他性的個讀寫鎖同時只能有個寫者或多個讀者(與CPU數相關),但不能同時既有讀者又有寫者。ide

 

相關函數爲:函數

1.初始化和銷燬讀寫鎖
    對於讀寫鎖變量的初始化能夠有兩種方式,一種是經過給一個靜態分配的讀寫鎖賦予常值PTHREAD_RWLOCK_INITIALIZER來初始化它,另 一種方法就是經過調用pthread_rwlock_init()來動態的初始化。而當某個線程再也不須要讀寫鎖的時候,能夠經過調用 pthread_rwlock_destroy來銷燬該鎖。函數原型以下:
spa

wKioL1dp92mT9NWOAAA_K01GRaY563.png 

這兩個函數若是執行成功均返回0,若是出錯則返回錯誤碼。
在釋放某個讀寫鎖佔用的內存以前,要先經過pthread_rwlock_destroy對讀寫鎖進行清理,釋放由pthread_rwlock_init所分配的資源。
在初始化某個讀寫鎖的時候,若是屬性指針attr是個空指針的話,表示默認的屬性;若是想要使用非默認屬性,則要使用到下面的兩個函數:
#include
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockatttr_t *attr);
這兩個函數一樣的,若是執行成功返回0,失敗返回錯誤碼。
這裏還須要說明的是,當初始化讀寫鎖完畢之後呢,該鎖就處於一個非鎖定狀態。
數據類型爲pthread_rwlockattr_t的某個屬性對象一旦初始化了,就能夠經過不一樣的函數調用來啓用或者是禁用某個特定的屬性。
2.獲取和釋放讀寫鎖
讀寫鎖的數據類型是pthread_rwlock_t,若是這個數據類型中的某個變量是靜態分配的,那麼能夠經過給它賦予常值 PTHREAD_RWLOCK_INITIALIZAR來初始化它。pthread_rwlock_rdlock()用來獲取讀出鎖,若是相應的讀出鎖已 經被某個寫入者佔有,那麼就阻塞調用線程。pthread_rwlock_wrlock()用來獲取一個寫入鎖,若是相應的寫入鎖已經被其它寫入者或者一 個或多個讀出者佔有,那麼就阻塞該調用線程;pthread_rwlock_unlock()用來釋放一個讀出或者寫入鎖。函數原型以下:
線程

wKiom1dp94-CJEtgAAAx3oAC75Y381.png

wKioL1dp-MuCCltEAAAxceg5LPE518.png

wKiom1dp-N2AT_4UAAAgrwoVMXQ620.png

 

這三個函數若調用成功則返回0,失敗就返回錯誤碼。要注意的是其中獲取鎖的兩個函數的操做都是阻塞操做,也就是說獲取不到鎖的話,那麼調用線程不是當即返 回,而是阻塞執行。有寫狀況下,這種阻塞式的獲取所得方式可能不是很適用,因此,接下來引入兩個採用非阻塞方式獲取讀寫鎖的函數 pthread_rwlock_tryrdlock()和pthread_rwlock_trywrlock(),非阻塞方式下獲取鎖的時候,若是不能馬 上獲取到,就會當即返回一個EBUSY錯誤,而不是把調用線程投入到睡眠等待。函數原型以下:
#include
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr);
一樣地,這兩個函數調用成功返回0,失敗返回錯誤碼。指針

下面舉一個關於讀寫鎖的小例子:orm

相關代碼:對象

#include<stdio.h>
#include<pthread.h>

pthread_rwlock_t rwlock;

int buf;
void *reader(void *arg)
{
    while(1)
    {
        pthread_rwlock_rdlock(&rwlock);
        printf("reader is reading:%d\n",buf);
        pthread_rwlock_unlock(&rwlock);
        sleep(1);
    }
}

void *writer(void *arg)
{
    int i=0;
    while(1)
    {
        pthread_rwlock_wrlock(&rwlock);
        buf =i++;
        printf("writer:%d\n",buf);
        pthread_rwlock_unlock(&rwlock);
        sleep(1);
    }
}

int main()
{
    pthread_t tid1,tid2,tid3;
    pthread_create(&tid1,NULL,writer,NULL);
    pthread_create(&tid2,NULL,reader,NULL);
    pthread_create(&tid3,NULL,reader,NULL);

    pthread_rwlock_init(&rwlock,NULL);

    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    pthread_join(tid3,NULL);

    return 0;
}

運行結果以下:blog

wKiom1dp-YXQbk30AAAz5-2bAFA374.png-wh_50

相關文章
相關標籤/搜索