其他分享
首页 > 其他分享> > 简单读写锁的实现研究

简单读写锁的实现研究

作者:互联网

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

当我们想实现一个读写锁的时候,我们需要清楚的知道:读写锁有哪些功能特点?读写锁的局限性?读写锁实现后的使用效果是什么?

下面是当前个人对读写锁的理解,仅供参考。

1. 读写锁用途

读写锁通常用于多线程处理程序中,用于保护线程共享资源的读写;
且通常适用共享资源读取较多,修改较少的场景中。

例如场景:
一些全局配置信息用于多线程任务的处理;对应配置信息的更新与适用就可以适用读写锁;
在这个场景中:
多线程任务处理申请读锁来获取最新的全局配置信息;
配置信息修改刷新申请写锁来更新全局配置信息;

2. 关于读写锁

读写锁的特点:

1-当有线程申请到读锁之后
申请读锁会立刻返回申请成功
申请写锁时,会等待现有的读锁都释放,才能申请到写锁;并且从申请开始,新的读锁申请会被拒绝。

2-当有线程申请到写锁之后
申请读锁会等待,会等待到现有的写锁释放
申请写锁会等待,也会等待到现有的写锁释放

其中需要特别注意的点是:

1-锁申请需要遵守一定的申请的序列:
写锁位于等待读锁完成释放状态时,会让后续申请读锁也进行等待,等待写锁释放后,后续的读锁才能进行申请。

2-写锁执行时,是不会像读锁那样有并行的,写锁执行时是单线程进入锁定处理的:
写锁锁定前需要等待之前读锁都释放,从而单线程执行;
也就是一到写锁申请,之前线程都会执行完释放读锁并等待,等待写锁拿到锁;

3. 简单实现

如果我们自己尝试实现一把读写锁,不考虑相应的异常情况,则实现上述目标应该就是一个基本合格的读写锁;

例如尝试使用std::mutex、std::conditon_varible、std::atomic来实现一把读写锁;

首先定义锁变量、条件变量、计数变量:

std::mutex wlock;
std::mutex condlock;
std::condition_varible cond;
std::atomic<int> readcount = 0;

然后实现其读锁申请,写锁申请,锁释放三个方法

读锁实现:
读锁申请一方面要保证没有写锁在申请中;
另一方面申请到后,读锁需要计数;

void readlock(){
  wlock.lock();
  ++readcount;
  wlock.unlock();
};

写锁实现:
写锁进入到申请状态后,需要拒绝后续的读写锁申请;
另外写锁需要等待之前申请的读锁都释放;

void writelock(){
  wlock.lock();
  while(readcount > 0){
    std::unqiue_lock<std::mutex> lock(&condlock, std::adopt_lock);
    cond.wait(lock);
    lock.release();
  }
};

锁释放实现:
锁释放需要区分两种情况,一种是读锁释放,一种是写锁释放;
读锁释放释放计数,并发通知有读锁释放;
写锁释放时,直接释放wlock即可。.

void release(){
  if (readcount > 0){
    --readcount;
    cond.notify_one();
  }
  else{
   wlock.unlock();
 }
}

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

标签:std,释放,实现,读写,申请,写锁,读锁,简单
来源: https://blog.csdn.net/chunyexiyu/article/details/123597936