【第22期】观点:IT 行业加班,到底有没有价值?

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程序设计学习笔记----多线程编程线程同步机制之互斥量(锁)与读写锁

互斥锁通信机制 基本原理 互斥锁以排他方式防止共享数据被并发访问,互斥锁是一个二元变量,状态为开(0)和关(1),将某个共享资源与某个互斥锁逻辑上绑定之后,对该资源的访问操作如下: (1)在访问该资...

线程同步机制的区别与比较及进程通信方法

有关多线程的一些技术问题:1、  何时使用多线程?2、  线程如何同步?3、  线程之间如何通讯?4、  进程之间如何通讯?先来回答第一个问题,线程实际主要应用于四个主要领域,当然各个领域之间不是绝对孤立的,他们有可能是重叠的,但是每个程序应该都可以归于某个领域:1、  offloading time-consu

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

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

ThreadLocal和线程同步机制相比有什么优势呢?

ThreadLocal和线程同步机制相比有什么优势呢? <p class="artcon"

解析JVM线程同步机制

解析JVM线程同步机制 <p align="center" class="
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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