实现线程读写锁的四种方法

对于某个临界资源的访问,读操作和写操作是要区别对待的。读操作可以多个线程同时进行,写操作必须互斥进行。

读写锁当已经被加了读锁时,其他的读模式锁请求仍然可以访问,但是写模式锁不能访问;当写模式锁加锁时,其他的请求都不能访问。


本文尝试用四种方法来完成读写锁的操作,都包含有写模式和读模式各自所要做的事情。

1、直接使用POSIX提供的读写锁

2、用条件变量实现读写锁

3、用互斥量实现读写锁

4、用信号量实现读写锁


直接使用读写锁

pthread中直接为我们提供的。
#include       //多线程、读写锁所需头文件

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_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_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      //线程信号量所需头文件

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);

你可能感兴趣的:(Linux,操作系统)