什麼是讀寫鎖:併發
讀寫鎖實際是種特殊的旋鎖,它把對共享資源的訪問者劃分紅讀者和寫者,讀者只對共享資源進讀訪問,寫者則須要對共享資源進寫操做。這種鎖相對於旋鎖,能提併發性,由於在多處理器系統中,它容許同時有多個讀者來訪問共享資源,最可能的讀者數爲實際的邏輯CPU數。寫者是排他性的個讀寫鎖同時只能有個寫者或多個讀者(與CPU數相關),但不能同時既有讀者又有寫者。ide
相關函數爲:函數
1.初始化和銷燬讀寫鎖
對於讀寫鎖變量的初始化能夠有兩種方式,一種是經過給一個靜態分配的讀寫鎖賦予常值PTHREAD_RWLOCK_INITIALIZER來初始化它,另 一種方法就是經過調用pthread_rwlock_init()來動態的初始化。而當某個線程再也不須要讀寫鎖的時候,能夠經過調用 pthread_rwlock_destroy來銷燬該鎖。函數原型以下:
spa
這兩個函數若是執行成功均返回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()用來釋放一個讀出或者寫入鎖。函數原型以下:
線程
這三個函數若調用成功則返回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