• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-159  評(píng)論-223  文章-30  trackbacks-0
               本文描述了一種簡(jiǎn)單的跨平臺(tái)鎖框架的設(shè)計(jì)與實(shí)現(xiàn),該框架小巧實(shí)用、易于擴(kuò)展,它的特點(diǎn)如下:
                 ● 實(shí)現(xiàn)了線程間互斥鎖
                 ● 實(shí)現(xiàn)優(yōu)化了單線程環(huán)境中的空鎖和空級(jí)別鎖
                 ● 支持編譯時(shí)或運(yùn)行時(shí)選擇鎖
                 ● 支持對(duì)象和類(lèi)級(jí)別的鎖粒度
                 ● 支持錯(cuò)誤或異常處理


            框架結(jié)構(gòu)
               由鎖抽象、鎖適配器、鎖守衛(wèi)、線程互斥鎖和鎖級(jí)別5個(gè)基本組件構(gòu)成,對(duì)應(yīng)類(lèi)的關(guān)系如下圖。
            基本組件
               鎖抽象
               提供鎖語(yǔ)義的抽象,一般有5種操作:創(chuàng)建或初始化、阻塞加鎖、非阻塞加鎖、解鎖和銷(xiāo)毀,實(shí)現(xiàn)為lock_base類(lèi)。
             1class lock_base
             2{
             3public:
             4    lock_base(){}
             5    virtual ~lock_base(){}
             6        
             7    virtual int lock() = 0;
             8    virtual int trylock() = 0;
             9    virtual int unlock() = 0;
            10}
            ;
               構(gòu)造對(duì)應(yīng)創(chuàng)建或初始化操作,析構(gòu)對(duì)應(yīng)銷(xiāo)毀操作,lock對(duì)應(yīng)阻塞加鎖,trylock對(duì)應(yīng)非阻塞加鎖,unlock對(duì)應(yīng)解鎖。 

               鎖適配器
               支持運(yùn)行時(shí)動(dòng)態(tài)綁定某個(gè)具體鎖,實(shí)現(xiàn)為lock_adapter類(lèi)模板,繼承l(wèi)ock_base。
             1 template<class T>
             2 class lock_adapter : public lock_base
             3{
             4public:
             5    lock_adapter(T &lock)
             6    :lock_(&lock)
             7    ,del_(false)
             8    {}
             9        
            10    lock_adapter()
            11    :del_(true)
            12    { lock_ = new T(); }
            13        
            14    ~lock_adapter()
            15    if(del_) delete lock_; }
            16        
            17    virtual int lock()
            18    return lock_->lock(); }
            19        
            20    virtual int trylock()
            21    return lock_->trylock(); }
            22        
            23    virtual int unlock()
            24    return lock->unlock(); }
            25        
            26private:
            27    T *lock_;
            28    bool del_;
            29}
            ;
               提供2個(gè)構(gòu)造函數(shù),支持引用外部鎖和構(gòu)造內(nèi)部鎖,并將方法實(shí)現(xiàn)委托給對(duì)應(yīng)的鎖實(shí)例。

               線程互斥鎖  
               一種支持線程間同步的具體鎖,支持windows和linux平臺(tái),實(shí)現(xiàn)為thread_mutex類(lèi)。  
             1thread_mutex::thread_mutex()
             2{
             3#ifdef _WIN32
             4    //because use SEH
             to handle API exception, so instead of using one free function to initialize the critical section 

             5    init_critical_section(&m_); 
             6#else
             7    int ret;
             8    if(ret=pthread_mutex_init(&m_,NULL))
             9        throw lock_error("pthread_mutex_init",ret);
            10#endif
            11}

            12
            13thread_mutex::~thread_mutex()
            14{
            15#ifdef _WIN32
            16    DeleteCriticalSection(&m_);
            17#else
            18    pthread_mutex_destroy(&m_);
            19#endif
            20}

            21
            22int thread_mutex::lock() 
            23
            24#ifdef _WIN32
            25    EnterCriticalSection(&m_);
            26    return 0;
            27#else
            28    int ret;
            29    if(ret=pthread_mutex_lock(&m_)){
            30        errno = ret;
            31        return -1;
            32    }

            33    return 0;
            34#endif
            35}

            36
            37int thread_mutex::trylock() 
            38
            39#ifdef _WIN32
            40#if (defined _WIN32_WINNT) && _WIN32_WINNT >= 0x0400
            41    if(!TryEnterCriticalSection(&m_)){
            42        errno = EBUSY;
            43        return -1;
            44    }

            45    return 0;
            46#endif    
            47    errno = ENOSYS;
            48    return -1;
            49#else
            50    int ret;
            51    if(ret=pthread_mutex_trylock(&m_)){
            52        errno = ret;
            53        return -1;
            54    }

            55    return 0;
            56#endif
            57}

            58
            59int thread_mutex::unlock()
            60
            61#ifdef _WIN32
            62    LeaveCriticalSection(&m_); 
            63    return 0;
            64#else
            65    int ret;
            66    if(ret = pthread_mutex_unlock(&m_)){
            67        errno = ret;
            68        return -1;
            69    }

            70    return 0;            
            71#endif
            72}
              lock、trylock和unlock返回0表示成;-1表示失敗,errno指示錯(cuò)誤碼; 當(dāng)僅用于單線程環(huán)境時(shí),加解鎖沒(méi)有意義,提供一個(gè)空鎖,實(shí)現(xiàn)為null_mutex類(lèi)。
            1class null_mutex
            2{
            3public:
            4    int lock() return 0;}
            5    int trylock() return 0;}
            6    int unlock() return 0; }
            7}
            ;

               鎖守衛(wèi)
               用于自動(dòng)獲取和釋放鎖,保證當(dāng)異常發(fā)生時(shí)能自動(dòng)解鎖,實(shí)現(xiàn)為lock_guard類(lèi)模板,T表示鎖類(lèi)型,只要這個(gè)類(lèi)型提供lock、trylock和unlock三種語(yǔ)義。
             1template<class T>
             2  class lock_guard : noncopyable
             3{
             4public:
             5    explicit lock_guard(T &lockbool block=true)
             6        : lock_(&lock)
             7    {
             8        owner_ = (block ? lock_->lock() : lock_->trylock());
             9    }

            10        
            11    ~lock_guard()
            12    {
            13        if(0==owner_) lock_->unlock();
            14    }

            15        
            16    int locked() const
            17    return owner_; }
            18    
            19private:
            20    T *lock_;
            21    int owner_; 
            22}
            ;
               構(gòu)造函數(shù)形參block為true表示阻塞加鎖,否則非阻塞加鎖。當(dāng)T為null_mutex時(shí),為了避免調(diào)用lock和unlock的開(kāi)銷(xiāo),特化如下。
            1template<>
            2class lock_guard<null_mutex>
            3{
            4    public:
            5        explicit lock_guard(null_mutex&){}
            6        ~lock_guard() {}
            7    }
            ;

               鎖級(jí)別
               提供類(lèi)級(jí)別和對(duì)象級(jí)別2種鎖粒度:類(lèi)級(jí)別是指所有對(duì)象共享同一個(gè)鎖,實(shí)現(xiàn)為class_level_lock類(lèi)模板;對(duì)象級(jí)別是指每個(gè)對(duì)象持有自己的鎖, 實(shí)現(xiàn)為object_level_lock類(lèi)模板。
             1template<class T>
             2class level_lock_base : noncopyable
             3{
             4public:
             5    typedef lock_guard<const T> lock_guard_type;
             6    
             7    int lock() const
             8    return static_cast<const T*>(this)->lock_.lock(); }
             9    
            10    int trylock() const
            11    return static_cast<const T*>(this)->lock_.trylock();}
            12  
            13    int unlock() const
            14    return static_cast<const T*>(this)->lock_.unlock(); }
            15    
            16protected:
            17    ~level_lock_base(){}
            18}
            ;
            19    
            20 template<class T,class L>
            21 class class_level_lock : public level_lock_base<class_level_lock<T,L> >
            22{
            23    template<class U> 
            24    friend class level_lock_base;
            25    
            26protected:
            27    ~class_level_lock(){}
            28    
            29private:
            30    static L lock_;        
            31}
            ;
            32    
            33 template<class T,class L>
            34 L class_level_lock<T,L>::lock_;
            35    
            36 template<class T,class L>
            37 class object_level_lock : public level_lock_base<object_level_lock<T,L> >
            38{
            39    template<class U> 
            40    friend class level_lock_base;
            41    
            42protected:
            43    ~object_level_lock(){}
            44    
            45private:
            46    mutable L lock_;    
            47}
            ;
               level_lock_base是為遵循DRY SPOT原則而衍生的基類(lèi),使用CRTP模式,T是繼承它的級(jí)別子類(lèi)類(lèi)型;它避免了每個(gè)子類(lèi)都要編寫(xiě)lock、trylock和unlock的冗余,并使用const T定義了鎖守衛(wèi)類(lèi)型別名,這是為了支持子類(lèi)的const方法。class_level_lock和object_level_lock中的T是宿主類(lèi)類(lèi)型,L是鎖類(lèi)型,當(dāng)L為null_mutex時(shí),為避免調(diào)用lock(或trylock)和unlock的開(kāi)銷(xiāo),提供了一個(gè)空級(jí)別,實(shí)現(xiàn)為null_level_lock類(lèi)模板,繼承l(wèi)evel_lock_base,并且必須要以它特化鎖守衛(wèi),這樣在實(shí)際使用時(shí)就不會(huì)引起"lock_不是null_level_lock<T,L>的成員"編譯錯(cuò)誤。
             1 template<class T,class L>
             2 class null_level_lock : public level_lock_base<null_level_lock<T,L> >
             3{
             4protected:
             5    ~null_level_lock(){}
             6}
            ;
             7    
             8 template<class T,class L>
             9 class lock_guard<const null_level_lock<T,L> >
            10{
            11public:
            12    explicit lock_guard(const null_level_lock<T,L>&){}
            13    ~lock_guard(){}
            14}
            ;

            應(yīng)用示例
               編譯時(shí)選擇鎖類(lèi)型與級(jí)別
               stl_sequence是以stl中的vector、list和deque三種序列容器為基礎(chǔ)進(jìn)行共性抽象的包裝容器,為了使它靈活支持各種鎖與級(jí)別,就需要將鎖和級(jí)別定義為模板參數(shù),并提供一個(gè)默認(rèn)的類(lèi)型。  
             1template<typename T,
             2         class L = null_mutex, //lock type
             3         template<class T,class L> class E = null_level_lock, //lock level
             4         template<class T,class U> class C = std::vector,
             5         template <class T> class U = std::allocator
             6         >
             7class stl_sequence : private E<stl_sequence<T,L,E,C,U>,L>
             8{
             9    typedef U<T> Allocator;
            10    typedef C<T,Allocator> cont_type;
            11    typedef stl_sequence<T,L,E,C,U> self_type;
            12    typedef E<self_type,L> base_type;
            13    typedef typename base_type::lock_guard_type lock_guard_type;
            14    
            15public:
            16    
            17    void add(const T &t,bool append = true)
            18    {
            19        lock_guard_type guard(*this);
            20        //do add thing
            21    }

            22
            23    void insert(size_t idx,const T &t)
            24    {
            25        lock_guard_type guard(*this);
            26        //do insert thing
            27    }

            28
            29    void erase(size_t idx)
            30    {
            31        lock_guard_type guard(*this);
            32        //do erase thing
            33    }

            34
            35    T* get(size_t idx) 
            36    {
            37        lock_guard_type guard(*this);
            38        //do get thing
            39    }

            40    
            41}
            ;
              從上可見(jiàn),增加、刪除、修改和查找操作都是通過(guò)首先調(diào)用lock_guard_type guard(*this)僅一行代碼來(lái)支持線程同步,下面來(lái)看看它的使用。
               ● 使用空級(jí)別鎖:seq1和seq2都沒(méi)有鎖,即使seq2使用了thread_mutex。
            1    stl_sequence<int> seq1;
            2    stl_sequence<int,thread_mutex> seq2;
               ● 使用對(duì)象級(jí)別鎖:seq3和seq4具有各自的鎖。
            1   stl_sequence<int,thread_mutex,object_level_lock> seq3, seq4;
               ● 使用類(lèi)級(jí)別鎖:seq5和seq6共享同一個(gè)鎖。
            1   stl_sequence<int,thread_mutex,class_level_lock> seq5, seq6;
               ● 使用空鎖:seq7、seq8和seq9都沒(méi)有鎖,但seq7效率稍高。
            1   stl_sequence<int,null_mutex> seq7;
            2   stl_sequence<int,null_mutex,class_level_lock> seq8;
            3   stl_sequence<int,null_mutex,object_level_lock> seq9;
               綜上可知,在單線程環(huán)境中,使用空級(jí)別空鎖就夠了;而在多線程環(huán)境中,可依據(jù)需求靈活選擇對(duì)象級(jí)別或類(lèi)級(jí)別鎖。

               運(yùn)行時(shí)綁定具體鎖
             1    lock_base *lb;
             2    if(argc>1 && 0==strcmp(argv[1],"thread_mutex"))
             3        lb = new lock_adapter<thread_mutex>(*(new thread_mutex));
             4    else
             5        lb = new lock_adapter<null_mutex> (*(new null_mutex));
             6  auto_ptr<lock_base> ap(lb);
             7  lock_guard<lock_base> guard(*lb); 
             8  //do some thing
            posted on 2014-12-28 23:38 春秋十二月 閱讀(2421) 評(píng)論(6)  編輯 收藏 引用 所屬分類(lèi): Opensrc

            評(píng)論:
            # re: 面向?qū)ο箧i框架的設(shè)計(jì)與實(shí)現(xiàn) 2014-12-30 08:31 | 萬(wàn)連文
            沒(méi)想到鎖搞這么復(fù)雜,多線程的問(wèn)題可以通過(guò)規(guī)劃線程模型來(lái)解決,底層的淫巧往往在于無(wú)鎖編程。  回復(fù)  更多評(píng)論
              
            # re: 面向?qū)ο箧i框架的設(shè)計(jì)與實(shí)現(xiàn) 2014-12-30 09:56 | 路人
            @萬(wàn)連文
            這種框架不復(fù)雜,和ACE的類(lèi)似,規(guī)劃線程模型離不開(kāi)鎖,無(wú)鎖編程也有很多問(wèn)題。  回復(fù)  更多評(píng)論
              
            # re: 面向?qū)ο箧i框架的設(shè)計(jì)與實(shí)現(xiàn) 2014-12-31 09:23 | Richard Wei
            哈哈, 我現(xiàn)在也比較趨向簡(jiǎn)單的設(shè)計(jì), 有時(shí)間玩模板的奇淫技巧, 還不如花時(shí)間解決幾個(gè)實(shí)際的問(wèn)題。
            曾經(jīng)思考過(guò)C++的編程風(fēng)格: http://www.shnenglu.com/weiym/archive/2013/04/27/199781.html  回復(fù)  更多評(píng)論
              
            # re: 面向?qū)ο箧i框架的設(shè)計(jì)與實(shí)現(xiàn)[未登錄](méi) 2014-12-31 10:47 | 春秋十二月
            @Richard Wei
            這些都是c++基本的東西,編譯器支持模板的差異性,庫(kù)開(kāi)發(fā)者就需要用奇淫技巧來(lái)跨平臺(tái),看boost的實(shí)現(xiàn)就知道了。c接口是最簡(jiǎn)潔通用的,應(yīng)當(dāng)首先。  回復(fù)  更多評(píng)論
              
            # re: 面向?qū)ο箧i框架的設(shè)計(jì)與實(shí)現(xiàn) 2014-12-31 14:49 | Richard Wei
            @春秋十二月
            理解, 基礎(chǔ)庫(kù)大量用模板我也沒(méi)反對(duì)...  回復(fù)  更多評(píng)論
              
            # re: 面向?qū)ο箧i框架的設(shè)計(jì)與實(shí)現(xiàn)[未登錄](méi) 2015-03-17 16:33 | aa
            有了boost庫(kù),再自己做簡(jiǎn)單跨平臺(tái)有些多余了  回復(fù)  更多評(píng)論
              
            久久精品中文字幕一区| 久久精品国产99国产精品导航| 国产精品九九久久免费视频 | 久久精品国产男包| 伊人久久大香线蕉综合Av | 久久99国产乱子伦精品免费| 久久发布国产伦子伦精品| 久久久久久毛片免费播放| 亚洲综合精品香蕉久久网97 | 少妇高潮惨叫久久久久久| 精品久久久久久国产潘金莲| 欧美日韩中文字幕久久伊人| 久久久综合香蕉尹人综合网| 亚洲精品午夜国产va久久| 久久亚洲春色中文字幕久久久| 国产亚洲欧美精品久久久| 国产精品VIDEOSSEX久久发布| 久久这里只有精品视频99| 亚洲精品无码久久一线| 72种姿势欧美久久久久大黄蕉| 国产91久久综合| 久久久精品人妻一区二区三区蜜桃| 国产产无码乱码精品久久鸭| 国产免费久久精品99久久| 国产精品久久新婚兰兰| 国产精品久久波多野结衣| 热综合一本伊人久久精品| 久久精品无码专区免费东京热| 久久精品二区| 久久天天躁狠狠躁夜夜96流白浆| 精品久久久久一区二区三区 | 久久av免费天堂小草播放| 99久久国产宗和精品1上映| 久久99国产精品久久| 思思久久好好热精品国产| 国内精品伊人久久久久| 中文字幕久久亚洲一区| 天天久久狠狠色综合| 色综合久久久久综合体桃花网 | 久久久久久久综合狠狠综合| 久久美女网站免费|