前言:上面一篇,我们介绍了互斥锁,这儿的读者写者问题需要用到自旋锁。


  1. 为什么会有自旋锁

   在编写多线程的时候,有些公共数据读的概率远远大于修改的几率。通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长。给这种代码段加锁,会极大地降低我们程序的效率。我们引入了读写锁即自旋锁处理这种多读少写的情况。


2.什么是自旋锁

(1)它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。

(2)这种锁相对于自旋锁而言,能提高并发性。

(3)在多处理器系统中:

    a.对于读者:它允许同时有多个读者来访问共享资源,最大可能的读者数为实际的逻辑CPU数。

    b.对于写者:写者是排他性的,一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。


3.相关函数

wKioL1ccy5Pgvr8fAAAtBbkR-L0772.png

wKioL1cczAby1GP1AAAnR0ivSnY810.png(基于写者)

wKiom1cczHGgYpfOAAAnyTSGWd8044.png(基于读者)


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


4.代码实现

 //test.c 
  1 #include<stdio.h>
  2 #include<pthread.h>
  3 
  4 pthread_rwlock_t lock;
  5 int g_val=0;
  6 
  7 void* read(void* arg)
  8 {
  9     while(1)
 10     {
 11         if(pthread_rwlock_rdlock(&lock)!=0)
 12         {
 13             printf("writer is writing,reader waiting...\n");
 14         }
 15         else
 16         {
 17             printf("reader%d read val is:%d\n",(int)arg,g_val);
 18             pthread_rwlock_unlock(&lock);
 19         }
 20         sleep(1);
 21     }
 22 }
 23 void* write(void* arg)
 24 {
 25     while(1)
 26     {
 27         if(pthread_rwlock_trywrlock(&lock)!=0)
 28         {
 29             printf("reader is reading,writer waiting...\n");
 30             sleep(1);
 31         }
 32         else
 33         {
 34             g_val++;
 35             printf("writer%d write val is:%d\n",(int)arg,g_val);
 36             pthread_rwlock_unlock(&lock);
 37         }
 38         sleep(1);
 39     }
 40 }
 41 int main()
 42 {
 43     pthread_rwlock_init(&lock,NULL);
 44     pthread_t writer1;
 45     pthread_t writer2;
 46 
 47     pthread_t reader1;
 48     pthread_t reader2;
 49     pthread_t reader3;
 50 
 51     pthread_create(&writer1,NULL,write,(void*)1);
 52     pthread_create(&writer2,NULL,write,(void*)2);
 53     pthread_create(&reader1,NULL,read,(void*)1);
 54     pthread_create(&reader2,NULL,read,(void*)2);
 55     pthread_create(&reader3,NULL,read,(void*)3);
 56 
 57     pthread_join(writer1,NULL);
 58     pthread_join(writer2,NULL);
 59     pthread_join(reader1,NULL);
 60     pthread_join(reader2,NULL);
 61     pthread_join(reader3,NULL);
 62 
 63     pthread_rwlock_destroy(&lock);
 64 
 65     return 0;
 66 }
 
 //makefile
 1 test:test.c
  2     gcc -o $@ $^ -lpthread
  3 .PHONY:clean
  4 clean:
  5     rm -f test

输出结果:

wKiom1cc2pzhwFOCAAA8ecehmT4399.png


5.结果分析:

由输出的结果知道,read中的

 printf("writer is writing,reader waiting...\n");

和write中的

printf("reader is reading,writer waiting...\n");

从未输出过知道,自旋锁设定为写的优先级高于读