實現線程讀寫鎖的四種方法

對於某個臨界資源的訪問,讀操作和寫操作是要區別對待的。讀操作可以多個線程同時進行,寫操作必須互斥進行。

讀寫鎖當已經被加了讀鎖時,其他的讀模式鎖請求仍然可以訪問,但是寫模式鎖不能訪問;當寫模式鎖加鎖時,其他的請求都不能訪問。


本文嘗試用四種方法來完成讀寫鎖的操作,都包含有寫模式和讀模式各自所要做的事情。

1、直接使用POSIX提供的讀寫鎖

2、用條件變量實現讀寫鎖

3、用互斥量實現讀寫鎖

4、用信號量實現讀寫鎖


直接使用讀寫鎖

pthread中直接爲我們提供的。
#include <pthread.h>      //多線程、讀寫鎖所需頭文件

pthread_rwlock_t  rwlock = PTHREAD_RWLOCK_INITIALIZER; //定義和初始化讀寫鎖

寫模式:
pthread_rwlock_wrlock(&rwlock);     //加寫鎖
寫寫寫……
pthread_rwlock_unlock(&rwlock);     //解鎖  



讀模式:
pthread_rwlock_rdlock(&rwlock);      //加讀鎖
讀讀讀……
pthread_rwlock_unlock(&rwlock);     //解鎖 

用條件變量實現讀寫鎖

這裏用條件變量+互斥鎖來實現。注意:條件變量必須和互斥鎖一起使用,等待、釋放的時候都需要加鎖。
#include <pthread.h> //多線程、互斥鎖所需頭文件

pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;      //定義和初始化互斥鎖
pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;       //定義和初始化條件變量


寫模式:
pthread_mutex_lock(&mutex);     //加鎖
while(w != 0 || r > 0)
{
     pthread_cond_wait(&cond, &mutex);      //等待條件變量的成立
}
w = 1;

pthread_mutex_unlock(&mutex);
寫寫寫……
pthread_mutex_lock(&mutex);
w = 0;
pthread_cond_broadcast(&cond);       //喚醒其他因條件變量而產生的阻塞
pthread_mutex_unlock(&mutex);    //解鎖


讀模式:
pthread_mutex_lock(&mutex);     
while(w != 0)
{
     pthread_cond_wait(&cond, &mutex);      //等待條件變量的成立
}
r++;
pthread_mutex_unlock(&mutex);
讀讀讀……
pthread_mutex_lock(&mutex);
r- -;
if(r == 0)
     pthread_cond_broadcast(&cond);       //喚醒其他因條件變量而產生的阻塞
pthread_mutex_unlock(&mutex);    //解鎖


用互斥鎖實現讀寫鎖

這裏使用2個互斥鎖+1個整型變量來實現。
#include <pthread.h> //多線程、互斥鎖所需頭文件
pthread_mutex_t r_mutex = PTHREAD_MUTEX_INITIALIZER;      //定義和初始化互斥鎖
pthread_mutex_t w_mutex = PTHREAD_MUTEX_INITIALIZER; 
int readers = 0;     //記錄讀者的個數

寫模式:
pthread_mutex_lock(&w_mutex);
寫寫寫……
pthread_mutex_unlock(&w_mutex);


讀模式:
pthread_mutex_lock(&r_mutex);         

if(readers == 0)
     pthread_mutex_lock(&w_mutex);
readers++;
pthread_mutex_unlock(&r_mutex); 
讀讀讀……
pthread_mutex_lock(&r_mutex);
readers- -;
if(reader == 0)
     pthread_mutex_unlock(&w_mutex);
pthread_mutex_unlock(&r_mutex); 

用信號量來實現讀寫鎖

這裏使用2個信號量+1個整型變量來實現。令信號量的初始數值爲1,那麼信號量的作用就和互斥量等價了。
#include <semaphore.h>     //線程信號量所需頭文件

sem_t r_sem;     //定義信號量
sem_init(&r_sem, 0, 1);     //初始化信號量 

sem_t w_sem;     //定義信號量
sem_init(&w_sem, 0, 1);     //初始化信號量  
int readers = 0;

寫模式:
sem_wait(&w_sem);
寫寫寫……
sem_post(&w_sem);


讀模式:
sem_wait(&r_sem);
if(readers == 0)
     sem_wait(&w_sem);
readers++;
sem_post(&r_sem);
讀讀讀……
sem_wait(&r_sem);
readers- -;
if(readers == 0)
     sem_post(&w_sem);
sem_post(&r_sem);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章