当前位置: 首页 > news >正文

读写锁RWLock简单实现研究

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

引言

读写锁在服务端程序开发时,用的还是比较广泛的一种锁,比较适合用于多读少写的场景。多读少写场景,可以减少加锁时间;因为能够对大多数的读场景减少加锁时间,也一定程度减少多线程程序的编写难度。

分析读写锁的实现

读锁的约束项:

  • 读锁时,需要能够计数,用于知道当前有多少个读锁在执行。
  • 读锁加锁时,计数增加;
  • 读锁解锁时,计数减少;
  • 有写锁加锁时和加锁后,读锁不能加锁;

写锁的约束项:

  • 写锁时,不需要计数
  • 写锁之间互斥,一次只有一个写锁加锁成功;
  • 写锁加锁和加锁后,之后的读锁加锁都等待;
  • 写锁要加锁成功,之前的读锁都需要释放完毕,读锁计数为0;

基于上面的简单实现

满足上面提到的要求,可以通过一个atomic做读锁计数,一个mutex做读写锁互斥量 进行简单的实现。

简单实现如下:
读锁加锁时,快速加解锁:加锁,++计数,解锁
读锁解锁时,不加锁:计数–
写锁加锁时:加锁,等待计数为0
写锁解锁时:解锁

#include <stdio.h>
#include <mutex>
#include <atomic>
#include <thread>
#include <unistd.h>
class rwlock
{
public:
    rwlock(){
	  _atomic.store(0);
	}
	void lockread(){
	  _mutex.lock();
	  _atomic++;
	  _mutex.unlock();
	}
	void unlockread(){
	  _atomic--;
	}
	void lockwrite(){
	  _mutex.lock();
	  while(_atomic.load() != 0){
	     continue;
	  }
	}
	void unlockwrite(){
	  _mutex.unlock();
	}
private:
	std::mutex _mutex;
	std::atomic<int> _atomic;
};

进一步完善

进一步完善,主要集中在几个点上

  • 写锁等待读锁完成时,使用信号量代替一直循环判断,可以在读锁unlockread时,发送信号量;或者读锁unlock发现计数为0时,发送信号量;写锁收到信号量后再判断;
  • atomic的load, store,可以使用std::memory_order_relaxed,提高一点读写速度;
  • 从测试效果看,mutex基本保证了申请锁次序与申请到锁次序一致性;否则的话,也要把这个次序考虑起来,这样就比较完善了;不会出现写锁与读锁前后申请,结果读锁先申请到了。

附加rwlock的测试程序与结果

测试程序:

rwlock lock;
void call1(int id){
  printf("enter call rlock %d\n", id);
  lock.lockread();
  printf("lockread %d\n", id);
  sleep(3);
  lock.unlockread();
  printf("unlockread %d\n", id);
}
void call2(int id){
  printf("enter call wlock %d\n", id);
  lock.lockwrite();
  printf("lockwrite %d\n", id);
  sleep(3);
  lock.unlockwrite();
  printf("unlockwrite %d\n", id);
}
int main(int argc, char** argv)
{
    std::thread t1(call1, 1);
	std::thread t2(call1, 2);
	std::thread t3(call2, 3);
	std::thread t4(call2, 4);
	std::thread t5(call1, 5);
	t1.join(); t2.join(); t3.join(); t4.join(); t5.join();
	return 0;
}

测试结果:

enter call rlock 1
lockread 1
enter call rlock 2
enter call wlock 4
enter call rlock 5
enter call wlock 3
lockread 2
unlockread 1
unlockread 2
lockwrite 4
unlockwrite 4
lockread 5
unlockread 5
lockwrite 3
unlockwrite 3

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

相关文章:

  • 有没有专业做盐的网站/seo导航站
  • 成品网站和模板建站/最近七天的新闻重点
  • 运营一个app需要多少钱?/seo网络推广哪家专业
  • 怎么打开google网站/百度seo优化价格
  • 班级展示网站/百度怎么做关键词优化
  • 机械类产品网站做优化/网络科技公司
  • 软件测试技术之利用 Jest 为 React 组件编写单元测试
  • JS入门到精通详解(9)
  • 【C语言进阶】自定义类型之结构体
  • mysql新建分区设置阈值(less than)引发的问题
  • 2.1总线概述
  • Android/Linux 子系统Graphics图形栈入门普法介绍
  • LocalDate方法使用总结
  • Open3D 点云投影至指定平面(Python版本)
  • 基于深度学习神经网络的农业病虫害识别(完整代码+数据)
  • Redis序列化、乱码问题
  • 【阶段四】Python深度学习01篇:深度学习基础知识:神经网络历史及优势、神经网络基础单元与梯度下降:正向传播和反向传播
  • (12)go-micro微服务JWT跨域认证