Linux线程编程 - 线程同步机制之读写锁通信机制

概述
读写锁与互斥量类似,不过读写锁允许更高的并行性。互斥量要么是锁住状态,要么是不加锁状态,而且一次只有一个线程对其加锁。读写锁可以有三种状态:读模式下加锁状态,写模式下加锁状态,不加锁状态。一次只有一个线程可以占有写模式的读写锁,但是多个线程可用同时占有读模式的读写锁。读写锁也叫做共享-独占锁,当读写锁以读模式锁住时,它是以共享模式锁住的,当它以写模式锁住时,它是以独占模式锁住的。

在对数据的读写应用中,更多的是读操作,而写操作较少,例如对数据库数据的读写应用。为了满足当前能够允许多个读出,但只允许一个写入的需求,线程提供了读写锁来实现。其基本原则如下:

(1)如果有其它线程读数据,则允许其它线程执行读操作,但不允许写操作;
(2)如果有其它线程写数据,则其它线程的读、写操作均允许。
因此,其将该锁分为了读锁和写锁。
(1)如果某线程申请了读锁,其它线程可以再申请读锁,但不能申请写锁;
(2)如果某线程申请了写锁,则其它线程不能申请读锁,也不能申请写锁。
定义读写锁对象的代码如下:

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. pthread_rwlock_t rwlock;            //全局变量  
读写锁操作函数


读写锁API
读写锁的数据类型为pthread_rwlock_t。如果这个类型的某个变量是静态分配的,那么可通过给它赋常值PTHREAD_RWLOCK_INITIALIZER来初始化它。
阻塞获取读写锁:

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. int pthread_rwlock_rdlock(pthread_rwlock_t *rwptr); //获取一个读出锁  
  2. int pthread_rwlock_wrlock(pthread_rwlock_t *rwptr); //获取一个写入锁  
都返回:成功时为0,出错时为正的Exxx值

非阻塞获取读写锁:

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);  
  2. int pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr);  
都返回:成功时为0,出错时为正的Exxx值

解锁:

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. int pthread_rwlock_unlock(pthread_rwlock_t *rwptr); //释放一个写入锁或者读出锁  
初始化和销毁读写锁:
[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. int pthread_rwlock_init(pthread_rwlock_t *rwptr, const pthread_rwlockattr_t *attr)  
  2. int pthread_rwlock_destroy(pthread_rwlock_t *rwptr);  
都返回:成功时为0,出错时为正的Exxx值
[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);  
  2. int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);  
都返回:成功时为0,出错时为正的Exxx值
[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *valptr);  
  2. int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int valptr);  
都返回:成功时为0,出错时为正的Exxx值

读写锁应用实例

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <errno.h>  
  2. #include <pthread.h>  
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5. #include <bits/pthreadtypes.h>  
  6.   
  7. static pthread_rwlock_t rwlock;  
  8.   
  9. #define WORK_SIZE 1024  
  10. char work_area[WORK_SIZE];  
  11. int time_to_exit;  
  12.   
  13. void *thread_function_read_o(void *arg);  
  14. void *thread_function_read_t(void *arg);  
  15. void *thread_function_write_o(void *arg);  
  16. void *thread_function_write_t(void *arg);  
  17.       
  18.   
  19. int main(int argc,char *argv[])   
  20. {  
  21.     int res;  
  22.     pthread_t a_thread,b_thread,c_thread,d_thread;  
  23.     void *thread_result;  
  24.   
  25.     res=pthread_rwlock_init(&rwlock,NULL);  
  26.     if (res != 0)   
  27.     {  
  28.         perror("rwlock initialization failed");  
  29.         exit(EXIT_FAILURE);  
  30.     }  
  31.     res = pthread_create(&a_thread, NULL, thread_function_read_o, NULL);//create new thread  
  32.     if (res != 0)   
  33.     {  
  34.         perror("Thread creation failed");  
  35.         exit(EXIT_FAILURE);  
  36.     }  
  37.   
  38.     res = pthread_create(&b_thread, NULL, thread_function_read_t, NULL);//create new thread  
  39.     if (res != 0)   
  40.     {  
  41.         perror("Thread creation failed");  
  42.         exit(EXIT_FAILURE);  
  43.     }  
  44.     res = pthread_create(&c_thread, NULL, thread_function_write_o, NULL);//create new thread  
  45.     if (res != 0)  
  46.     {  
  47.         perror("Thread creation failed");  
  48.         exit(EXIT_FAILURE);  
  49.     }  
  50.     res = pthread_create(&d_thread, NULL, thread_function_write_t, NULL);//create new thread  
  51.     if (res != 0)  
  52.     {  
  53.         perror("Thread creation failed");  
  54.         exit(EXIT_FAILURE);  
  55.     }  
  56.       
  57.     res = pthread_join(a_thread, &thread_result);             
  58.     if (res != 0)   
  59.     {  
  60.          perror("Thread join failed");  
  61.          exit(EXIT_FAILURE);  
  62.     }  
  63.     res = pthread_join(b_thread, &thread_result);             
  64.     if (res != 0)   
  65.     {  
  66.          perror("Thread join failed");  
  67.          exit(EXIT_FAILURE);  
  68.     }  
  69.     res = pthread_join(c_thread, &thread_result);             
  70.     if (res != 0)   
  71.     {  
  72.         perror("Thread join failed");  
  73.         exit(EXIT_FAILURE);  
  74.     }  
  75.     res = pthread_join(d_thread, &thread_result);             
  76.     if (res != 0)   
  77.     {  
  78.        perror("Thread join failed");  
  79.        exit(EXIT_FAILURE);  
  80.     }  
  81.      
  82.     pthread_rwlock_destroy(&rwlock);                  
  83.     exit(EXIT_SUCCESS);  
  84. }  
  85.   
  86. void *thread_function_read_o(void *arg)  
  87. {  
  88.     printf("thread read one try to get lock\n");      
  89.       
  90.     pthread_rwlock_rdlock(&rwlock);  
  91.     while(strncmp("end", work_area, 3) != 0)   
  92.     {  
  93.         printf("this is thread read one.");  
  94.         printf("the characters is %s",work_area);     
  95.         pthread_rwlock_unlock(&rwlock);           
  96.         sleep(2);  
  97.         pthread_rwlock_rdlock(&rwlock);           
  98.         while (work_area[0] == '\0' )          
  99.         {  
  100.             pthread_rwlock_unlock(&rwlock);   
  101.             sleep(2);  
  102.             pthread_rwlock_rdlock(&rwlock);  
  103.         }  
  104.     }     
  105.     pthread_rwlock_unlock(&rwlock);   
  106.     time_to_exit=1;  
  107.     pthread_exit(0);  
  108. }  
  109.   
  110.  void *thread_function_read_t(void *arg)  
  111. {  
  112.     printf("thread read one try to get lock\n");  
  113.     pthread_rwlock_rdlock(&rwlock);  
  114.     while(strncmp("end", work_area, 3) != 0)   
  115.     {  
  116.         printf("this is thread read two.");  
  117.         printf("the characters is %s",work_area);     
  118.         pthread_rwlock_unlock(&rwlock);           
  119.         sleep(5);  
  120.         pthread_rwlock_rdlock(&rwlock);           
  121.         while (work_area[0] == '\0' )          
  122.         {                 
  123.             pthread_rwlock_unlock(&rwlock);   
  124.             sleep(5);  
  125.             pthread_rwlock_rdlock(&rwlock);   
  126.         }  
  127.     }  
  128.     pthread_rwlock_unlock(&rwlock);   
  129.     time_to_exit=1;  
  130.     pthread_exit(0);  
  131. }  
  132.   
  133. void *thread_function_write_o(void *arg)  
  134. {  
  135.     printf("this is write thread one try to get lock\n");  
  136.     while(!time_to_exit)   
  137.     {  
  138.         pthread_rwlock_wrlock(&rwlock);  
  139.         printf("this is write thread one.\nInput some text. Enter 'end' to finish\n");  
  140.         fgets(work_area, WORK_SIZE, stdin);  
  141.         pthread_rwlock_unlock(&rwlock);  
  142.         sleep(15);  
  143.     }  
  144.     pthread_rwlock_unlock(&rwlock);  
  145.     pthread_exit(0);  
  146. }  
  147.   
  148. void *thread_function_write_t(void *arg)  
  149. {  
  150.     sleep(10);  
  151.     while(!time_to_exit)  
  152.     {  
  153.         pthread_rwlock_wrlock(&rwlock);  
  154.         printf("this is write thread two.\nInput some text. Enter 'end' to finish\n");   
  155.         fgets(work_area, WORK_SIZE, stdin);  
  156.         pthread_rwlock_unlock(&rwlock);  
  157.         sleep(20);  
  158.     }  
  159.     pthread_rwlock_unlock(&rwlock);  
  160.     pthread_exit(0);  
  161. }  
运行结果:

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. $ ./pthread_rwlock_example   
  2. this is write thread one try to get lock  
  3. thread read one try to get lock  
  4. this is write thread one.  
  5. Input some text. Enter 'end' to finish  
  6. thread read one try to get lock  
  7. wr one test  
  8. this is thread read two.the characters is wr one test  
  9. this is thread read one.the characters is wr one test  
  10. this is thread read one.the characters is wr one test  
  11. this is thread read one.the characters is wr one test  
  12. this is thread read two.the characters is wr one test  
  13. this is write thread two.  
  14. Input some text. Enter 'end' to finish  
  15. wr two test  
  16. this is thread read one.the characters is wr two test  
  17. this is thread read two.the characters is wr two test  
  18. this is thread read one.the characters is wr two test  
  19. this is write thread one.  
  20. Input some text. Enter 'end' to finish  
  21. end  

原文链接:

http://blog.csdn.net/geng823/article/details/41344735

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值