原文作者:@玄冬Wong
转载请注明原文出处:http://aigo.iteye.com/blog/2296462
key world: std::shared_mutex、std::mutex、performance、benchmark、性能测试
shared_mutex的适用场景比较特殊:一个或多个读线程同时读取共享资源,且只有一个写线程来修改这个资源,这种情况下才能从shared_mutex获取性能优势。
cppreference文档
http://en.cppreference.com/w/cpp/thread/shared_mutex
Shared mutexes are usually used in situations when multiple readers can access the same resource at the same time without causing data races, but only one writer can do so.
测试代码:
注意,VC第一个支持shared_mutex的版本是VS2015 update2
/************************************************************************/ /* std::shared_mutex与std::mutex的性能对比 */ /************************************************************************/ #pragma once #define WRITE_THREAD_COUNT 8 #define LOOP_COUNT 5000000 #include <iostream> #include <mutex> // For std::unique_lock #include <shared_mutex> #include <thread> class shared_mutex_counter { public: shared_mutex_counter() = default; // Multiple threads/readers can read the counter's value at the same time. unsigned int get() const { std::shared_lock<std::shared_mutex> lock(mutex_); return value_; } // Only one thread/writer can increment/write the counter's value. void increment() { std::unique_lock<std::shared_mutex> lock(mutex_); value_++; } // Only one thread/writer can reset/write the counter's value. void reset() { std::unique_lock<std::shared_mutex> lock(mutex_); value_ = 0; } private: mutable std::shared_mutex mutex_; unsigned int value_ = 0; }; class mutex_counter { public: mutex_counter() = default; unsigned int get() const { std::unique_lock<std::mutex> lk(mutex_); return value_; } void increment() { std::unique_lock<std::mutex> lk(mutex_); value_++; } private: mutable std::mutex mutex_; unsigned int value_ = 0; }; void test_shared_mutex() { shared_mutex_counter counter; int temp; auto writer = [&counter]() { for (int i = 0; i < LOOP_COUNT; i++) { counter.increment(); } }; auto reader = [&counter, &temp]() { for (int i = 0; i < LOOP_COUNT; i++) { temp = counter.get(); } }; std::thread** tarray = new std::thread*[WRITE_THREAD_COUNT]; clock_t start = clock(); for (int i = 0; i < WRITE_THREAD_COUNT; i++) { tarray[i] = new std::thread(reader); } std::thread tw(writer); for (int i = 0; i < WRITE_THREAD_COUNT; i++) { tarray[i]->join(); } tw.join(); clock_t end = clock(); printf("[test_shared_mutex]\n"); printf("thread count:%d\n", WRITE_THREAD_COUNT); printf("result:%d cost:%dms temp:%d \n", counter.get(), end - start, temp); } void test_mutex() { mutex_counter counter; int temp; auto writer = [&counter]() { for (int i = 0; i < LOOP_COUNT; i++) { counter.increment(); } }; auto reader = [&counter, &temp]() { for (int i = 0; i < LOOP_COUNT; i++) { temp = counter.get(); } }; std::thread** tarray = new std::thread*[WRITE_THREAD_COUNT]; clock_t start = clock(); for (int i = 0; i < WRITE_THREAD_COUNT; i++) { tarray[i] = new std::thread(reader); } std::thread tw(writer); for (int i = 0; i < WRITE_THREAD_COUNT; i++) { tarray[i]->join(); } tw.join(); clock_t end = clock(); printf("[test_mutex]\n"); printf("thread count:%d\n", WRITE_THREAD_COUNT); printf("result:%d cost:%dms temp:%d \n", counter.get(), end - start, temp); } int main() { //为了排除测试程序的无关因素,测试时只开启一个 //test_shared_mutex(); test_mutex(); }
测试结果:
2线程抢占
[test_mutex]
thread count:2
result:10000000 cost:1348ms temp:10000000
[test_shared_mutex]
thread count:2
result:10000000 cost:699ms temp:10000000
4线程抢占
[test_mutex]
thread count:4
result:10000000 cost:2448ms temp:10000000
[test_shared_mutex]
thread count:4
result:10000000 cost:1233ms temp:10000000
8线程抢占
[test_mutex]
thread count:8
result:5000000 cost:2452ms temp:5000000
[test_shared_mutex]
thread count:8
result:5000000 cost:1123ms temp:3231860
结论:
在多个只读线程和一个写线程的情况下,shared_mutex比mutex快一倍。
PS:std::shared_mutex和std::mutex分别对应java中的ReentrantReadWriteLock、ReentrantLock。
相关推荐
在x86_64 CPU上生成的原子操作和C ++ 11内存壁垒以及汇编程序指令
Mutex 又称互斥量,C++ 11中与 Mutex 相关的类(包括锁类型)和函数都声明在 <mutex> 头文件中,所以如果你需要使用 std::mutex,就必须包含 <mutex> 头文件。 <mutex> 头文件介绍 Mutex 系列类(四种) std::mutex,...
前面两讲《C++11 并发指南二(std::thread 详解) 》,《C++11 并发指南三(std::mutex 详解) 》分别介绍了 std::thread 和 std::mutex,相信读者对 C++11 中的多线程编程有了一个最基本的认识,本文将介绍 C++11 标准...
object_threadsafe:我们将任何对象的线程安全性和std :: shared_mutex的速度提高10倍,以实现读取率> 85%的无锁算法的速度
C++11中的各种mutex, lock对象,实际上都是对posix的mutex,condition的封装。不过里面也有很多细节值得学习。 std::mutex 先来看下std::mutex: 包增了一个pthread_mutex_t __m_,很简单,每个函数该干嘛...
AudioPlayer
#0 0x00002b9405ea1c38 in __lll_mutex_lock_wait () from /lib64/libc.so.6 #1 0x00002b9405e45e5f in _L_lock_4026 () from /lib64/libc.so.6 #2 0x00002b9405e42df1 in free () from /lib64/libc.so.6 #3 0x00002...
它比boost::shared_mutex快。 lock_shared非常贪婪,因此等待lock时间是不公平的。 这应该没有问题,因为此互斥对象适用于被动写入器-主动读取器方案。 最好情况下, lock_shared只是一个fetch_add 。 在最佳...
# include " lucy.h "# include < condition># include < cstdio># include < mutex>std::mutex g_mutex;std::condition_variable g_finished;std::mutex g_finished_mutex;void print ( const char * msg
openSL_test_case 产生“W/libOpenSLES(8768): frameworks/wilhelm/src/android/AudioPlayer_to_android.cpp:410: pthread 0x69fc0ce8 (tid 10263) see object 0x6a001c08 was locked by pthread 0x4008thelid41/...
可以练习线程的基本操作、线程锁和条件变量等技术。完整代码如下。代码后面附有主要语句的讲解。 #include #include #include <mutex> #include std::mutex data_mutex; std::condition_variable data_var; bool...
ucos-ii中互斥信号mutex建立源码
32位android中bionic是32位的,其中的mutex只有一半也就是16位能够存储pid,当通过docker运行android时,大概率pid会超过16位的范围,就可能会导致android中mutex死锁,表现为应用卡住黑屏。 [32-bit ABI bugs]...
那是: 创建线程-std :: thread, 锁定-std :: mutex,std :: condition_variable等。 时间-std :: chrono,std :: sleep_for等期货-std :: assync,std :: promise,std :: future等。 std :: notify_all_at_...
lock_guard 对象通常用于管理某个锁(Lock)对象,因此与 Mutex RAII 相关,方便线程对互斥量上锁,即在某个 lock_guard 对象的声明周期内,它所管理的锁对象会一直保持上锁状态;而 lock_guard 的生命周期结束之后,...
Latch_Lock_And_Mutex_Contention_Troubleshooting
NACHOS 线程与同步 将实验一中的线程改为安全的
在做多线程编程时,有两个场景我们都会遇到: 多线程访问共享资源,需要用到锁; 多线程间的状态同步,这个可用...std::mutex g_mutex; // 用到的全局锁 std::condition_variable g_cond; // 用到的条件变量 int g_i
多线程之间的同步与互斥,详情看博客:http://blog.csdn.net/mybelief321/article/details/9390707