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

原创 2016年08月29日 09:02:56

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

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

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

  1. pthread_rwlock_t rwlock;            //全局变量  
读写锁操作函数


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

  1. int pthread_rwlock_rdlock(pthread_rwlock_t *rwptr); //获取一个读出锁  
  2. int pthread_rwlock_wrlock(pthread_rwlock_t *rwptr); //获取一个写入锁  
都返回:成功时为0,出错时为正的Exxx值

非阻塞获取读写锁:

  1. int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);  
  2. int pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr);  
都返回:成功时为0,出错时为正的Exxx值

解锁:

  1. int pthread_rwlock_unlock(pthread_rwlock_t *rwptr); //释放一个写入锁或者读出锁  
初始化和销毁读写锁:
  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值
  1. int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);  
  2. int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);  
都返回:成功时为0,出错时为正的Exxx值
  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值

读写锁应用实例

  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. }  
运行结果:

  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

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Linux线程同步机制三--读写锁rwlock

Linux 线程同步机制 读写锁

Linux 线程同步机制:互斥、读写锁、条件变量

//1.互斥 //互斥量数据类型: pthread_mutex_t mutex; //初始化互斥量: int pthread_mutex_init(ptread_mutex_t *res...

线程同步机制:互斥量、信号量、读写锁、条件变量

一、互斥量(mutex)   互斥量本质上是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。   对互斥量进行加锁以后,任何其它试图再次对互斥量加锁的线程将会被阻塞...

linux多线程-----同步机制(互斥量、读写锁、条件变量)

linux多线程-----同步机制(互斥量、读写锁、条件变量)

linux下多线程同步机制之信号量、互斥量、读写锁、条件变量

之前有写过类似的博客,这东西不用老忘,现在又有更清晰的理解了。 一、信号量 信号量最基本的两个操作就是PV操作:P()操作实现信号量减少,V()操作实现信号量的增加 信号量的值取决于信号量的类型,信号...
  • ylf13
  • ylf13
  • 2013-10-29 16:39
  • 5674

线程间同步机制----读写锁

一、读写锁基本原理 读写锁与互斥锁类似,不过读写锁运行更高的并行。互斥量要么锁住状态,要么就是不加锁状态,而且一次只有一个线程可以对其加锁。读写锁可以有3中状态:读模式下加锁状态,写模式下加锁状态...

Linux系统编程——线程同步与互斥:读写锁

读写锁基本原理 当有一个线程已经持有互斥锁时,互斥锁将所有试图进入临界区的线程都阻塞住。但是考虑一种情形,当前持有互斥锁的线程只是要读访问共享资源,而同时有其它几个线程也想读取这个共享资源,但是...

【原创】《Linux高级程序设计》杨宗德著 - Linux多线程编程 - 线程同步机制

【原创】《Linux高级程序设计》杨宗德著 - Linux多线程编程 - 线程同步机制

Linux线程同步机制一--互斥锁mutex

Linux 线程同步机制 互斥锁

Windows核心编程之 用户模式下的线程同步 读写锁和条件变量

读写锁 条件变量
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)