1. 程式人生 > >Linux環境程式設計之同步(三):讀寫鎖

Linux環境程式設計之同步(三):讀寫鎖

概述

相互排斥鎖把試圖進入我們稱之為臨界區的全部其它執行緒都堵塞住。該臨界區通常涉及對由這些執行緒共享一個或多個數據的訪問或更新。讀寫鎖在獲取讀寫鎖用於讀某個資料和獲取讀寫鎖用於寫直接作差別。

讀寫鎖的分配規則例如以下:

1、僅僅要沒有執行緒持有某個給定的讀寫鎖用於寫。那麼隨意數目的執行緒能夠持有該讀寫鎖用於讀。

2、僅當沒有執行緒持有某個給定的讀寫鎖用於讀或用於寫時,才幹分配該讀寫鎖用於寫。

即僅僅要沒有執行緒在改動某個給定的資料,那麼隨意數目的執行緒都能夠擁有該資料的讀訪問權。僅當沒有其它執行緒在讀或改動某個給定的資料時。當前執行緒才幹夠改動它。

這樣的對於某個給定資源的共享訪問也稱為共享-獨佔上鎖

,由於獲取一個讀寫鎖用於讀稱為共享鎖。獲取一個讀寫鎖用於寫稱為獨佔鎖

獲取與釋放讀寫鎖

讀寫鎖的資料型別為pthread_rwlock_t。假設這個型別的某個變數是靜態分配的。則可通過給它賦常值PTHREAD_RWLOCK_INITIALIZER來初始化它。

pthread_rwlock_rdlock獲取一個讀出鎖。假設相應的讀寫鎖已由某個寫入者持有。那就堵塞呼叫執行緒。pthread_rwlock_wrlock獲取一個寫入鎖,假設相應的讀寫鎖已由還有一個寫入者持有,或者已由一個或多個讀出者持有,那就堵塞呼叫執行緒。pthread_rwlock_unlock釋放一個讀出鎖或寫入鎖。

#include <pthread.h>
int	pthread_rwlock_rdlock(pthread_rwlock_t *rwptr);
int	pthread_rwlock_wrlock(pthread_rwlock_t *rwptr);
int	pthread_rwlock_unlock(pthread_rwlock_t *rwptr);    //成功返回0,出錯返回為正的EXXX值。
以下兩個函式嘗試獲取一個讀出鎖或寫入鎖。但假設該鎖不能立即取得,那就返回一個EBUSY錯誤,而不是呼叫執行緒投入睡眠。

#include <pthread.h>
int	pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);
int	pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr); //成功返回0,出錯返回正值
讀寫鎖屬性
給靜態分配的讀寫鎖賦值PTHREAD_RWLOCK_INITIALIZER來初始化它。

讀寫鎖變數也可通過呼叫pthread_rwlock_init來動態地初始化。

噹噹一個執行緒不再須要某個讀寫鎖時。可呼叫pthread_rwlock_destroy摧毀它。

#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *rwptr, const pthread_rwlockattr_t *attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwptr);							//成功為0,出錯為正值
初始化某個讀寫鎖時,假設attr是空指標。就使用預設屬性。

要賦予它非預設的屬性,須要使用例如以下兩個函式:

#include <pthread.h>
int pthread_rwlockattr_init(pthread_rwlockattr_t *rwptr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *rwptr);							//成功為0,出錯為正值
資料型別為pthread_rwlockattr_t的某個屬性物件一旦初始化。就通過呼叫不同的函式來啟用或禁止特定屬性。

當前定義了的唯一屬性是PTHREAD_PROCESS_SHARED,它指定相應的讀寫鎖將不同程序間共享,而不僅僅是在單個程序內的不同執行緒間共享。以下兩個函式分別獲取和設定這個屬性。

#include <pthread.h>
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *valptr);
int pthread_rwlockattr_setpshared(const pthread_rwlockattr_t *attr, int value);  //成功返回0,出錯返回正值

讀寫鎖的實現可參考《UNP2》P142