一.概述:

  有一种情况:即对一些公共资源的访问操作很多,但修改操作比较少,而访问操作往往伴随着查找操作,中间耗时很长。此时如果用互斥锁的话,一个线程会在读操作内待的时间比较长,如果是多线程就会降低并发性。而如果用读写锁,其并发性会大大提高(理论上,有多少个cpu就会有多少个线程同时进行读操作),从而提高程序的效率。

  读写锁必须维持三种关系:读者之间不能互斥(即没有关系),写者之间要互斥,读者与写者之间要互斥和同步。

  读写锁是一种特殊的自旋锁。自旋锁:当条件不成立的时候会一直询问(轮询)直到条件满足。(适合于在锁内待的时间较少(可以减少线程调度))。

  读写锁的三种状态:

  1.当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞
  2.当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权,但是以写模式 对它进行加锁的线程将会被阻塞
  3.当读写锁在读模式的锁状态时,如果有另外的线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁的请求,这样可以避免读模式锁长期占用,而等待的写模式锁请求则长期阻塞。




二.相关函数:

(1).pthread_rwlock_init:int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,

                                                                               const pthread_rwlockattr_t *restrict attr)

rwlock参数:输出型参数。

attr参数:设置读写锁的状态,一般为NULL。

返回值:成功返回0,失败返回错误码。


(2).pthread_rwlock_destroy:int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)

函数功能:销毁一共读写锁,并释放其资源。

返回值:成功返回0,失败返回错误码。


(3).pthread_rwlock_rdlock函数:int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)

函数功能:以读加锁状态进行加锁。(阻塞式的)

返回值:成功返回0,失败返回错误码。


(4).thread_rwlock_tryrdlock函数:int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)

函数功能:以读加锁状态进行加锁。(非阻塞式的)

返回值:成功返回0,失败返回错误码。


(5).thread_rwlock_wrlock函数:int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)

函数功能:以写加锁状态进行加锁。(阻塞式的)

返回值:成功返回0,失败返回错误码。


(6).thread_rwlock_trywrlock函数:int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)

函数功能:以写加锁状态进行加锁。(非阻塞式的)

返回值:成功返回0,失败返回错误码。


(7).thread_rwlock_unlock函数:int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)

函数功能:对rwlock进行解锁。

返回值:成功返回0,失败返回错误码。




三.相关代码:

 1 #include<stdio.h>                                                                                                                                              
  2 #include<pthread.h>
  3 
  4 int g_data = 0;
  5 pthread_rwlock_t rw_lock;
  6 
  7 void* writer(void* arg)
  8 {
  9     while(1)
 10     {
 11         pthread_rwlock_wrlock(&rw_lock);
 12         g_data++;
 13         pthread_rwlock_unlock(&rw_lock);
 14         sleep(3);     //注意要加在锁的外面,过5秒获得写锁,其它时间都是读者
 15     }
 16 }
 17 
 18 void* reader(void* arg)
 19 {
 20 
 21     while(1)
 22     {
 23         pthread_rwlock_rdlock(&rw_lock);
 24         printf("the g_data is: %d\n ",g_data);
 25         pthread_rwlock_unlock(&rw_lock);
 26         sleep(1);
 27     }
 28 }
 29 
 30 
 31 int main()
 32 {
 33     pthread_rwlock_init(&rw_lock, NULL);
 34     pthread_t tid1, tid2;
 35     pthread_create(&tid1, NULL, writer, NULL);
 36     pthread_create(&tid2, NULL, reader, NULL);
 37     pthread_join(tid1, NULL);
 38     pthread_join(tid2, NULL);
 39     return 0;
 40 }

执行结果:

wKiom1cfQJzD4M0xAAA4o7dBkXo758.png



总结:读写锁适用于对一共公共资源的读操作进行多,而写操作进行少的情况。在这种情况下可以提高读操作的并发性,因为读写锁中的对读操作的线程并没有互斥,理论上有多少个cpu就会有多少个线程在并发进行读操作。