并发编程之线程的读写锁

目录

1.概念

2.读写锁的状态

3.读写锁特性

 4.读写锁的适用场景

 5.主要数据类型和应用函数

6.编码举例


1.概念

读写锁实际上是一种特殊的自旋锁,它把共享资源的访问划分成读者和写者,读者只能拥有对共享资源的读权限,写者则需要对共享资源进行写操作。读写锁并不是两把锁,它是一个名字叫做读写锁的锁,可以拥有读模式下加锁状态,写模式下加锁状态和不加锁者三种状态。它与互斥量类似,对比互斥量,使用读写锁可以使得运行有更高的并行性。

2.读写锁的状态

a.读模式下加锁状态(读锁)
b.写模式下加锁状态(写锁)
c.不加锁状态

3.读写锁特性

精炼概括:写独占,读共享。
更具体点可如下:
1.读写锁是“写模式加锁”时(写锁),解锁前,所有对该锁加锁的线程都会被阻塞;
2.读写锁是“读模式加锁”时(读锁),如果T1中读锁已经加锁成功了,此时来了三个其他线程,分情况讨论:
  T1以读模式加锁成功,T2,T3,T4都请求写锁,T2,T3,T4都会阻塞,后续写锁自由竞争;
  T1以读模式加锁成功,T2请求写,T3和T4请求读,此时T2,T3,T4都会被阻塞,但是等待T1完成读释放锁之后,优先满足写线程T2,之后满足T3和T4的读请求,因为写锁请求的T2的优先级高.
  T1以读模式加锁成功,T2,T3,T4都请求读锁,可共享去读。
  

 4.读写锁的适用场景

读写锁非常适合于对数据结构读的次数远远大于写的情况。

 5.主要数据类型和应用函数

读写锁数据类型
读写锁变量实例
pthread_rwlock_tpthread_rwlock_t rwlock(定义了一个读写锁变量rwlock)
头文件:
#include <pthread.h>
函数体:
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
返回值:
以上共7个函数的返回值在成功情况下都返回0,失败的时候i返回int类型的错误号。

6.编码举例

/*
作者:Muten
编码日期:20201016
代码功能:三个写线程对全局共享资源变量进行读操作,五个读线程对全局共享资源变量进行读操作
编码目的:演示读写锁的使用
运行环境:
Linux localhost.localdomain 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
*/


#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int counter;            // 定义全局共享资源变量
pthread_rwlock_t rwlock;// 定义全局读写锁变量
// 写线程
void *th_write(void* arg)
{
   int t;
   int i = (int) arg;
   while(1)
   {
     t = counter;
     usleep(1000);
     pthread_rwlock_wrlock(&rwlock);
     printf("**********************************************write thread %d: %lu : counter = %d, ++counter = %d\n",i,pthread_self(),t,++counter);
     pthread_rwlock_unlock(&rwlock);
     usleep(5000);
   }
   return NULL;
}
// 读线程
void *th_read(void* arg)
{
   int i = (int) arg;
   while(1)
   {
     pthread_rwlock_rdlock(&rwlock);
     printf("read thread %d: %lu : counter = %d\n",i,pthread_self(),counter);
     pthread_rwlock_unlock(&rwlock);
     usleep(900);
   }
   return NULL;
}

int main()
{
  int i ;
  pthread_t tid[8];
  pthread_rwlock_init(&rwlock,NULL);
  for(i = 0;i<3;i++)
      pthread_create(&tid[i],NULL,th_write,(void*)i);
  for(i = 0;i<5;i++)
      pthread_create(&tid[i+5],NULL,th_read,(void*)i);

  for(i = 0;i<8;i++)
      pthread_join(tid[i],NULL);
  pthread_rwlock_destroy(&rwlock); 
  return 0;
}

7.读写锁的实现探索

pthread_rwlock读写锁的使用细节

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值