当前位置:网站首页>手撕读写锁性能测试
手撕读写锁性能测试
2022-07-30 12:13:00 【君梦如烟Brian】
测试代码
基本思路:
先用CountDownLatch (详见下节,并发用具) 同步子线程创建,然后,摁下计时器一次,开始测试。
再用另一个CountDownLatch 同步子线程完成任务的情况,最后再按一下计时器。
配置:
1个写线程,7个读线程。同时,内部控制读写次数,为了方便体现读写锁的性能与互斥锁的性能对比,直接调整内部循环的限制次数即可。
粗略的结果:
在写的次数比读的次数要少得多时,读写锁性能比互斥锁要高。
在写得次数比读得次数差不多时,互斥锁性能比读写锁略高。
但是在开启代码优化后,只有写者数量少于读者数量的两个数量级左右,读写锁的性能才开始体现出来。
CountDownLatch startLatch(1);
CountDownLatch endLatch(8);
ReadWriteLock mtx;
int g_count = 0;
void write_something() {
startLatch.wait();
int count = 1000; // thread_local
do {
WriterLockGuard lock(::mtx);
g_count++;
} while (--count);
endLatch.down();
}
void read_something() {
startLatch.wait();
int count = 100000; // thread_local
do {
#ifndef TEST_RWLOCK
WriterLockGuard lock(::mtx);
#else
ReaderLockGuard lock(::mtx);
#endif
} while (--count);
endLatch.down();
}
int main()
{
using namespace std::chrono;
std::vector<std::thread> threads;
for (int i = 0; i != 7; ++i) {
threads.push_back(thread(read_something));
}
for (int i = 0; i != 1; ++i) {
threads.push_back(thread(write_something));
}
startLatch.down();
auto start = std::chrono::system_clock::now();
endLatch.wait();
auto end = std::chrono::system_clock::now();
cout << (g_count == 1000) << endl;
cout << duration_cast<milliseconds>(end - start).count() << " ms" << endl;
for (auto &th : threads) {
th.join();
}
return 0;
}
读写锁实现代码
互斥锁 + 条件变量实现读写锁
class ReadWriteLock {
std::atomic<int> nwait_;
std::condition_variable isNotWriter_;
std::mutex mtx_;
public:
void reader_lock() {
unique_lock<std::mutex> localGuard(mtx_);
while (nwait_ < 0) {
isNotWriter_.wait(localGuard);
}
nwait_++;
}
void reader_unlock() {
lock_guard<std::mutex> localGuard(mtx_);
if (--nwait_ == 0) isNotWriter_.notify_one();
}
void writer_lock() {
unique_lock<std::mutex> localGuard(mtx_);
while (nwait_ != 0) {
isNotWriter_.wait(localGuard);
}
--nwait_;
assert(nwait_ == -1);
}
void writer_unlock() {
lock_guard<std::mutex> localGuard(mtx_);
++nwait_;
assert(nwait_ == 0);
isNotWriter_.notify_all();
}
};
双互斥锁实现读写锁
class ReadWriteLock {
int nwait_;
std::mutex rmtx_;
std::mutex wmtx_;
public:
ReadWriteLock() :nwait_(0) {
}
void reader_lock() {
lock_guard<std::mutex> localGuard(rmtx_);
++nwait_;
if (nwait_ == 1) wmtx_.lock();
}
void reader_unlock() {
lock_guard<std::mutex> localGuard(rmtx_);
--nwait_;
if (nwait_ == 0) wmtx_.unlock();
}
void writer_lock() {
wmtx_.lock();
}
void writer_unlock() {
wmtx_.unlock();
}
};
并发用具
CountDownLatch
java常见的同步工具, 通常用于子线程全部完成任务后汇总给主线程
class CountDownLatch {
size_t count_ = 0;
std::mutex mtx_;
std::condition_variable cond_;
public:
CountDownLatch(size_t count):count_(count) {
assert(count >= 1);
}
void down() {
unique_lock<std::mutex> localGurad(mtx_);
if (--count_ == 0) cond_.notify_all();
}
void wait() {
unique_lock<std::mutex> localGurad(mtx_);
while (count_ != 0) cond_.wait(localGurad);
}
};
LocalGuard
一些巧妙利用RALL机制的线程同步工具
读写锁相关
WriterLockGuard:
class WriterLockGuard {
ReadWriteLock &lock_;
public:
WriterLockGuard(ReadWriteLock& lock) :lock_(lock) {
lock_.writer_lock();
}
~WriterLockGuard() {
lock_.writer_unlock();
}
};
ReaderLockGuard:
class ReaderLockGuard {
ReadWriteLock &lock_;
public:
ReaderLockGuard(ReadWriteLock& lock) :lock_(lock){
lock_.reader_lock();
}
~ReaderLockGuard() {
lock_.reader_unlock();
}
};
更多参考
边栏推荐
- 【ASP.NET Core】选项类的依赖注入
- New:WebKitX ActiveX :::Crack
- shell的理解
- 物理服务器与虚拟机:主要区别和相似之处
- 爱可可AI前沿推介(7.30)
- Niuke-TOP101-BM42
- Verilog grammar basics HDL Bits training 08
- 北上广线下活动丨年底最不可错过的技术聚会都齐了
- Bagging-Blending Multi-Model Fusion Short-Term Electricity Load Forecasting Based on Weighted Grey Correlation Projection
- 看了这些6G原型样机,我想一觉睡到2030年
猜你喜欢

即时通讯-改变社交与工作状态的新型软件
![[BJDCTF2020]Cookie is so stable-1|SSTI注入](/img/48/34955bbe3460ef09a5b8213c7cc161.png)
[BJDCTF2020]Cookie is so stable-1|SSTI注入

Win11打不开exe应用程序怎么办?Win11无法打开exe程序解决方法

Beijing, Shanghai and Guangzhou offline events丨The most unmissable technology gatherings at the end of the year are all gathered
![[SCTF2019]Flag Shop](/img/26/20e21ec873f41f2633703216453a44.png)
[SCTF2019]Flag Shop

概率论的学习整理--番外1:可重复且无次序的计数公式C(n+k-1,k) 的例题 : 同时丢3个骰子,会有多少种情况?答案不是216而是56!

Zhou Hongyi: Microsoft copied the 360 security model and became the largest security company in the United States

数据湖(十八):Flink与Iceberg整合SQL API操作

Apifox generates interface documentation tutorial and operation steps

维护数千规模MySQL实例,数据库灾备体系构建指南
随机推荐
概率论的学习整理--番外2:和二项式,组合相关的杨辉三角
Win11打不开exe应用程序怎么办?Win11无法打开exe程序解决方法
腰部外骨骼机器人线性自抗扰控制器参数优化
Matlab基础(1)——基础知识
反转链表-递归反转法
爱可可AI前沿推介(7.30)
嵌入式环境下并发控制与线程安全
win下怎么搭建php环境的方法教程
使用百度EasyDL实现明厨亮灶厨师帽识别
[SCTF2019]Flag Shop
即时通讯-改变社交与工作状态的新型软件
External Force Estimation Based on Time Delay Estimation with Perturbed Kalman Filter
双击Idea图标打不开——解决办法
【MySQL系列】-B+树索引和HASH索引有什么区别
CMake library search function does not search LD_LIBRARY_PATH
云原生应用的概念和云原生应用的 15 个特征
Rust 从入门到精通02-安装
13-GuliMall Basics Summary
初级永磁直线电机双动子电流镜像容错控制
ModelCoder状态机:对柴油机工况判断策略进行建模