视频教程:https://www.bilibili.com/video/av86491201
C++11中的互斥量
互斥量 | 说明 |
---|---|
std::mutex | 独占的互斥量,不能递归使用 |
std::timed_mutex | 有超时功能的独占互斥量,不能递归使用 |
std::recursive_mutex | 递归互斥量,能递归使用 |
std::recursive_timed_mutex | 有超时功能的递归互斥量 |
C++14中引入std::shared_mutex
- std::shared_mutex用于管理可转移和共享所有权的互斥对象,适用场景比较特殊:一个或多个读线程同时读取共享资源,且只有一个写线程来修改这个资源,这种情况下才能从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
- http://en.cppreference.com/w/cpp/thread/shared_mutex
互斥量管理类-锁
- shared_lock是read lock。搭配std::shared_mutex使用,被锁后仍允许其他线程执行同样被shared_lock的代码。
- lock_guard和unique_lock是write lock。被锁后不允许其他线程执行被shared_lock或unique_lock的代码。
- 通常我们这样定义:
typedef std::shared_lock<std::shared_mutex> ReadLock;
typedef std::lock_guard<std::shared_mutex> WriteLock;
std::shared_mutex和std::mutex的性能对比
// C++_Shard_Mutex_Sample.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <mutex>
#include <shared_mutex>
#include <thread>
#include <list>
#include <iostream>
#include <vector>
#define READ_THREAD_COUNT 8
#define LOOP_COUNT 5000000
typedef std::shared_lock<std::shared_mutex> ReadLock;
typedef std::lock_guard<std::shared_mutex> WriteLock;
typedef std::lock_guard<std::mutex> NormalLock;
class shared_mutex_counter {
public:
shared_mutex_counter() = default;
unsigned int get() const {
ReadLock lock(mutex);
return value;
}
void increment() {
WriteLock lock(mutex);
value++;
}
private:
mutable std::shared_mutex mutex;
unsigned int value = 0;
};
class mutex_counter {
public:
mutex_counter() = default;
unsigned int get() const {
NormalLock lock(mutex);
return value;
}
void increment() {
NormalLock lock(mutex);
value++;
}
private:
mutable std::mutex mutex;
unsigned int value = 0;
};
class timers
{
public:
timers()
{
m_begin = std::chrono::high_resolution_clock::now();
}
~timers()
{
m_end = std::chrono::high_resolution_clock::now();
Consuming();
}
void Consuming()
{
std::cout << "Time-consuming:" << std::chrono::duration_cast<std::chrono::duration<float, std::milli>>(m_end - m_begin).count() << std::endl;
}
private:
std::chrono::high_resolution_clock::time_point m_begin;
std::chrono::high_resolution_clock::time_point m_end;
};
void test_shared_mutex()
{
shared_mutex_counter counter;
unsigned int temp;
auto writer = [&counter]() {
for (unsigned int i = 0; i < LOOP_COUNT; i++){
counter.increment();
}
};
auto reader = [&counter, &temp]() {
for (unsigned int i = 0; i < LOOP_COUNT; i++) {
temp = counter.get();
}
};
std::cout << "----- shared mutex test ------" << std::endl;
std::list<std::shared_ptr<std::thread>> threadlist;
{
timers timer;
for (int i = 0; i < READ_THREAD_COUNT; i++)
{
threadlist.push_back(std::make_shared<std::thread>(reader));
}
std::shared_ptr<std::thread> pw = std::make_shared<std::thread>(writer);
for (auto &it : threadlist)
{
it->join();
}
pw->join();
}
std::cout <<"count:"<< counter.get() << ", temp:" << temp << std::endl;
}
void test_mutex()
{
mutex_counter counter;
unsigned int temp;
auto writer = [&counter]() {
for (unsigned int i = 0; i < LOOP_COUNT; i++) {
counter.increment();
}
};
auto reader = [&counter, &temp]() {
for (unsigned int i = 0; i < LOOP_COUNT; i++) {
temp = counter.get();
}
};
std::cout << "----- mutex test ------" << std::endl;
std::list<std::shared_ptr<std::thread>> threadlist;
{
timers timer;
for (int i = 0; i < READ_THREAD_COUNT; i++)
{
threadlist.push_back(std::make_shared<std::thread>(reader));
}
std::shared_ptr<std::thread> pw = std::make_shared<std::thread>(writer);
for (auto &it : threadlist)
{
it->join();
}
pw->join();
}
std::cout << "count:" << counter.get() << ", temp:" << temp << std::endl;
}
int main()
{
test_shared_mutex();
test_mutex();
return 0;
}
//output
----- shared mutex test ------
Time-consuming:4309.85
count:5000000, temp:5000000
----- mutex test ------
Time-consuming:10541.4
count:5000000, temp:4953412
性能提升效果明显
网友评论