美文网首页
C++14_std::shared_mutex的用法

C++14_std::shared_mutex的用法

作者: JasonLiThirty | 来源:发表于2020-02-03 15:51 被阅读0次

    视频教程: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
    

    性能提升效果明显

    参考://https://www.iteye.com/blog/aigo-2296462

    相关文章

      网友评论

          本文标题:C++14_std::shared_mutex的用法

          本文链接:https://www.haomeiwen.com/subject/brvqxhtx.html