免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
c++11 atomic_flag實現(xiàn)高效的mutex

 c++11線程庫提供了std::mutex,方便地實現(xiàn)跨平臺的互斥鎖,提供了std::atomic模板實現(xiàn)原子操作。但標準中沒有強制要求std::atomic模板的各種實例化保證提供的操作接口是真正的無鎖實現(xiàn),標準中要求保證是無鎖實現(xiàn)的只有std::atomic_flag類,此類沒有 lock unlock try_lock接口,只有test_and_set和clear。利用std::atomic_flag可以方便地實現(xiàn)跨平臺的旋轉(zhuǎn)鎖。旋轉(zhuǎn)鎖的效率要比std::mutex高出很多,但CPU的使用率也要高出很多。為了兼具高效率和低CPU使用率,可以在加鎖時先按旋轉(zhuǎn)鎖方式嘗試一定的次數(shù),如果指定次數(shù)嘗試加鎖失敗再轉(zhuǎn)而調(diào)用等待。以下是c++11的實現(xiàn),按照通用做法,提供 lock unlock try_lock三個操作接口:

#ifndef __SPIN_MUTEX_H_

#define __SPIN_MUTEX_H_

#include <mutex>

#include <atomic>

#include <chrono>

#include <condition_variable>

class spin_lock

{

public:

    spin_lock()

    {

        flg_.clear(std::memory_order_release);

    }

    ~spin_lock() = default;

public:

    void lock()

    {

        for (; flg_.test_and_set(std::memory_order_acquire););

    }

    bool try_lock()

    {

        int _try_cnt = 100;

        for (; _try_cnt > 0 && flg_.test_and_set(std::memory_order_acquire); --_try_cnt);

        if (_try_cnt > 0)

            return true;

        return false;

    }

    void unlock()

    {

        flg_.clear(std::memory_order_release);

    }

private:

    spin_lock(const spin_lock&) = delete;

    spin_lock(spin_lock&&) = delete;

    spin_lock& operator=(const spin_lock&) = delete;

    spin_lock& operator=(spin_lock&&) = delete;

private:

    std::atomic_flag flg_;

};

class spin_mutex

{

public:

    spin_mutex()

    {

        flg_.clear(std::memory_order_release);

    }

    explicit spin_mutex(int _try_cnt)

        : try_cnt_(_try_cnt)

    {

        flg_.clear(std::memory_order_release);

    }

    ~spin_mutex() = default;

public:

    void lock()

    {

        for (int millis = 5;; millis = (millis < 100 ? millis << 2 : millis))

        {

            int _try_cnt = try_cnt_;

            for (; _try_cnt > 0 && flg_.test_and_set(std::memory_order_acquire); --_try_cnt);

            if (_try_cnt > 0)

                return;

            std::unique_lock<std::mutex> ulk(mut_);

            cond_.wait_for(ulk, std::chrono::milliseconds(millis));

        }

    }

    bool try_lock()

    {

        int _try_cnt = try_cnt_;

        for (; _try_cnt > 0 && flg_.test_and_set(std::memory_order_acquire); --_try_cnt);

        if (_try_cnt > 0)

            return true;

        return false;

    }

    void unlock()

    {

        flg_.clear(std::memory_order_release);

        cond_.notify_all();

    }

private:

    spin_mutex(const spin_mutex&) = delete;

    spin_mutex(spin_mutex&&) = delete;

    spin_mutex& operator=(const spin_mutex&) = delete;

    spin_mutex& operator=(spin_mutex&&) = delete;

private:

    std::mutex mut_;

    std::atomic_flag flg_;

    std::condition_variable cond_;

    int try_cnt_{ 200 };

};

#endif

        spin_lock是直接使用std::atomic_flag,lock時不停地嘗試加鎖直到成功,參見cppreference.com上的示例。

        spin_mutex類實現(xiàn)了和std::mutex一樣的功能,加鎖時先循環(huán)指定次數(shù)加鎖,加鎖成功即返回,加鎖失敗即進入等待,注意這里的條件變量等待只能使用wait_for并且等待的時間不能太長,因為條件變量有兩個缺點:假喚醒和先喚醒再等待無法等待返回。因為我們的spin_mutex加解鎖靠的僅僅是std::atomic_flag,mutex和condition_variable僅僅是用作一個等待作用以不至于CPU使用率太高,因此這里用wait_for就避免開了條件變量的兩個缺點。wait_for等待的時間先是很短,嘗試次數(shù)增多再增加等待時間,以減少CPU使用率且出現(xiàn)先喚醒再等待時不會等待很長時間。解鎖的時候先解鎖,再調(diào)用notify_all喚醒所有等待線程立即開始搶占。

--------------------- 

作者:mymodian 

來源:CSDN 

原文:https://blog.csdn.net/mymodian9612/article/details/53728176 

版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Linux鎖機制
如何實現(xiàn)C 中的多線程編程
C++:線程(std::thread)
C++11 并發(fā)指南三(std::mutex 詳解)
互斥鎖和信號量的區(qū)別
Linux 內(nèi)核的同步機制,第 1 部分
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服