线程读写锁的实现

转载:http://blog.csdn.net/ojshilu/article/details/25244389

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

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


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

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

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

3、用互斥量实现读写锁

4、用信号量实现读写锁


直接使用读写锁

pthread中直接为我们提供的。
[cpp]  view plain  copy
  1. #include <pthread.h>      //多线程、读写锁所需头文件  
  2.   
  3. pthread_rwlock_t  rwlock = PTHREAD_RWLOCK_INITIALIZER; //定义和初始化读写锁  
  4.   
  5. 写模式:  
  6. pthread_rwlock_wrlock(&rwlock);     //加写锁  
  7. 写写写……  
  8. pthread_rwlock_unlock(&rwlock);     //解锁    
  9.   
  10.   
  11.   
  12. 读模式:  
  13. pthread_rwlock_rdlock(&rwlock);      //加读锁  
  14. 读读读……  
  15. pthread_rwlock_unlock(&rwlock);     //解锁   

用条件变量实现读写锁

这里用条件变量+互斥锁来实现。注意:条件变量必须和互斥锁一起使用,等待、释放的时候都需要加锁。
[cpp]  view plain  copy
  1. #include <pthread.h> //多线程、互斥锁所需头文件  
  2.   
  3. pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;      //定义和初始化互斥锁  
  4. pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;       //定义和初始化条件变量  
  5.   
  6.   
  7. 写模式:  
  8. pthread_mutex_lock(&mutex);     //加锁  
  9. while(w != 0 || r > 0)  
  10. {  
  11.      pthread_cond_wait(&cond, &mutex);      //等待条件变量的成立  
  12. }  
  13. w = 1;  
  14.   
  15. pthread_mutex_unlock(&mutex);  
  16. 写写写……  
  17. pthread_mutex_lock(&mutex);  
  18. w = 0;  
  19. pthread_cond_broadcast(&cond);       //唤醒其他因条件变量而产生的阻塞  
  20. pthread_mutex_unlock(&mutex);    //解锁  
  21.   
  22.   
  23. 读模式:  
  24. pthread_mutex_lock(&mutex);       
  25. while(w != 0)  
  26. {  
  27.      pthread_cond_wait(&cond, &mutex);      //等待条件变量的成立  
  28. }  
  29. r++;  
  30. pthread_mutex_unlock(&mutex);  
  31. 读读读……  
  32. pthread_mutex_lock(&mutex);  
  33. r- -;  
  34. if(r == 0)  
  35.      pthread_cond_broadcast(&cond);       //唤醒其他因条件变量而产生的阻塞  
  36. pthread_mutex_unlock(&mutex);    //解锁  


用互斥锁实现读写锁

这里使用2个互斥锁+1个整型变量来实现。
[cpp]  view plain  copy
  1. #include <pthread.h> //多线程、互斥锁所需头文件  
  2. pthread_mutex_t r_mutex = PTHREAD_MUTEX_INITIALIZER;      //定义和初始化互斥锁  
  3. pthread_mutex_t w_mutex = PTHREAD_MUTEX_INITIALIZER;   
  4. int readers = 0;     //记录读者的个数  
  5.   
  6. 写模式:  
  7. pthread_mutex_lock(&w_mutex);  
  8. 写写写……  
  9. pthread_mutex_unlock(&w_mutex);  
  10.   
  11.   
  12. 读模式:  
  13. pthread_mutex_lock(&r_mutex);           
  14.   
  15. if(readers == 0)  
  16.      pthread_mutex_lock(&w_mutex);  
  17. readers++;  
  18. pthread_mutex_unlock(&r_mutex);   
  19. 读读读……  
  20. pthread_mutex_lock(&r_mutex);  
  21. readers- -;  
  22. if(reader == 0)  
  23.      pthread_mutex_unlock(&w_mutex);  
  24. pthread_mutex_unlock(&r_mutex);   

用信号量来实现读写锁

这里使用2个信号量+1个整型变量来实现。令信号量的初始数值为1,那么信号量的作用就和互斥量等价了。
[cpp]  view plain  copy
  1. #include <semaphore.h>     //线程信号量所需头文件  
  2.   
  3. sem_t r_sem;     //定义信号量  
  4. sem_init(&r_sem, 0, 1);     //初始化信号量   
  5.   
  6. sem_t w_sem;     //定义信号量  
  7. sem_init(&w_sem, 0, 1);     //初始化信号量    
  8. int readers = 0;  
  9.   
  10. 写模式:  
  11. sem_wait(&w_sem);  
  12. 写写写……  
  13. sem_post(&w_sem);  
  14.   
  15.   
  16. 读模式:  
  17. sem_wait(&r_sem);  
  18. if(readers == 0)  
  19.      sem_wait(&w_sem);  
  20. readers++;  
  21. sem_post(&r_sem);  
  22. 读读读……  
  23. sem_wait(&r_sem);  
  24. readers- -;  
  25. if(readers == 0)  
  26.      sem_post(&w_sem);  
  27. sem_post(&r_sem);  

猜你喜欢

转载自blog.csdn.net/smilesundream/article/details/78080443