• <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>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            利用引用計數(shù)在多線程中安全釋放資源

            轉(zhuǎn)自http://blog.csdn.net/SeaWave/archive/2006/05/21/747863.aspx

            本文是觀大寶SODMEBLOG中文章有感,原文中提到了兩種方法(對數(shù)據(jù)緩沖區(qū)使用引用計數(shù)機(jī)制、在clientsock的對象設(shè)計機(jī)制上使釋放操作線性化),但只討論了第2種方法的實現(xiàn)。其實在多線程程序里,要讓一個釋放操作線性化,并不是一件容易的事情,這不僅僅是多個IOCP工作線程的問題(一般來說,我們會為每個CPU設(shè)立兩個IOCP工作線程),還涉及到其他業(yè)務(wù)邏輯線程的問題。

            比方說,我們通常(就象文中也提到的)會將ClientSocket與接收緩沖區(qū)綁定到一個會話對象中(為簡化起見,發(fā)送數(shù)據(jù)往往沒有用overlapped機(jī)制,而是直接用一個異步send,也就不需要發(fā)送緩沖區(qū)),而這個對象可能被除IOCP工作線程以外的其他線程也用到,比方說一個事件隊列的處理線程(我們會在收到數(shù)據(jù)的時候生成事件對象置入隊例中,以類似于Command模式的方法來處理,而這些事件對象會引用到會話對象),或者,也許有某個容器會存放這些會話對象的一個引用,用于定時發(fā)送心跳包、會話計數(shù)、檢索等等,這個時候,會話對象的銷毀就不是那么簡單的了,換句話說,僅靠將銷毀工作統(tǒng)一到執(zhí)行GetQueuedCompletionStatus的函數(shù)里是不夠的。

            在這種情況下,文中提到的第1采用引用計數(shù)的方法就比較優(yōu)雅了,在我的很多實際應(yīng)用中,都是將會話對象設(shè)計為可引用計數(shù)的,不暴露它的析構(gòu)函數(shù),而是當(dāng)引用計數(shù)減到0的時候,自動銷毀,這樣就保證僅當(dāng)沒有任何人使用它的時候才會釋放它

            利用C++的模板,可以十分方便地模擬出自動引用計數(shù)的安全指針:

            001: /************************************************************************
             002:    
            引用計數(shù)基類、及引用計數(shù)指針模板類
             003:        
            ----NoSound QQ2591570 可隨意復(fù)制、改動、使用、拍磚,概不追究!
             004: ************************************************************************/
             005: #ifndef _REFCOUNTED_INCLUDED_
             006: #define _REFCOUNTED_INCLUDED_
             007:
             008: #include <cassert>
             009: #ifdef _MT
             010: #include <Windows.h>
             011: #endif
             012:
             013: class RefCountable {
             014: public:
             015:     int addRef(void) {
             016:         #ifdef _MT
             017:         return ::InterlockedIncrement(&refCount_);
             018:         #else
             019:         return ++refCount_;
             020:         #endif
             021:     }
             022:
             023:     int decRef(void) {
             024:         int r =
             025:             #ifdef _MT
             026:             ::InterlockedDecrement(&refCount_);
             027:             #else
             028:             --refCount_;
             029:             #endif
             030:         assert(r>=0);
             031:         if (0==r)
             032:             delete this;
             033:         return r;
             034:     }
             035:
             036:     int getRefCount(void) const { return refCount_; }
             037:
             038: protected:
             039:     RefCountable(void) : refCount_(0) {}
             040:     virtual ~RefCountable(void) { assert(0==refCount_); }
             041:
             042: private:
             043:     #ifdef _MT
             044:     long
             045:     #else
             046:     int
             047:     #endif
             048:     refCount_;
             049:     RefCountable(const RefCountable &);
             050:     RefCountable & operator = (const RefCountable &);
             051: };
             052:
             053: template<class T>
             054: class RefCountedPtr {
             055: public:
             056:     RefCountedPtr(void) : ptr_(0) {}
             057:     RefCountedPtr(T *ptr) : ptr_(ptr) {
             058:         if (ptr_)
             059:             ptr_->addRef();
             060:     }
             061:     RefCountedPtr(const RefCountedPtr<T> &sour) : ptr_(sour.ptr_) {
             062:         if (ptr_)
             063:             ptr_->addRef();
             064:     }
             065:     RefCountedPtr & operator = (const RefCountedPtr<T> &right) {
             066:         if (this!=&right) {
             067:             if (0!=ptr_)
             068:                 ptr_->decRef();
             069:             ptr_ = right.ptr_;
             070:             if (ptr_)
             071:                 ptr_->addRef();
             072:         }
             073:         return *this;
             074:     }
             075:     ~RefCountedPtr(void) {
             076:         if (0!=ptr_)
             077:             ptr_->decRef();
             078:     }
             079:
             080:     T & operator*() const { return *ptr_; }
             081:     T * operator->() const { return (&**this); }
             082:    
             083:     friend bool operator == (const RefCountedPtr<T> &left, const RefCountedPtr<T> &right) {
             084:         return (left.ptr_ == right.ptr_);
             085:     }
             086:     friend bool operator != (const RefCountedPtr<T> &left, const RefCountedPtr<T> &right) {
             087:         return (left.ptr_ != right.ptr_);
             088:     }
             089:     friend bool operator < (const RefCountedPtr<T> &left, const RefCountedPtr<T> &right) {
             090:         return (left.ptr_ < right.ptr_);
             091:     }
             092:     friend bool operator > (const RefCountedPtr<T> &left, const RefCountedPtr<T> &right) {
             093:         return (left.ptr_ > right.ptr_);
             094:     }
             095:     friend bool operator <= (const RefCountedPtr<T> &left, const RefCountedPtr<T> &right) {
             096:         return (left.ptr_ <= right.ptr_);
             097:     }
             098:     friend bool operator >= (const RefCountedPtr<T> &left, const RefCountedPtr<T> &right) {
             099:         return (left.ptr_ >= right.ptr_);
             100:     }
             101:
             102:     bool isNull() const { return 0==ptr_; }
             103:     bool isValid() const { return 0!=ptr_; }
             104:
             105:     //
            返回所控制的對象指針
             106:     T * get(void) const { return ptr_; }
             107:
             108:     //
            取得對另一指針的控制權(quán)
             109:     void reset(T * ptr=0) {
             110:         if (0!=ptr)
             111:             ptr->addRef();
             112:         if (0!=ptr_)
             113:             ptr_->decRef();
             114:         ptr_ = ptr;
             115:     }
             116:
             117: private:
             118:     T    *ptr_;
             119: };
             120:
             121: #endif // ifndef _REFCOUNTED_INCLUDED_

             

            posted on 2011-04-21 12:38 肥仔 閱讀(2030) 評論(0)  編輯 收藏 引用 所屬分類: C++ 基礎(chǔ)

            色狠狠久久综合网| 久久精品国产精品亚洲| 久久精品国产久精国产果冻传媒| 久久久久久一区国产精品| 欧美亚洲另类久久综合婷婷| 日本精品久久久久影院日本| 久久午夜免费视频| 精品久久无码中文字幕| 日本久久久久久中文字幕| 久久久久这里只有精品| 久久亚洲国产精品成人AV秋霞 | 精品人妻伦九区久久AAA片69| 久久精品成人影院| 久久99精品国产麻豆宅宅| 国产亚洲综合久久系列| 久久精品国产只有精品66| 久久久久亚洲精品日久生情| 99国产欧美久久久精品蜜芽 | 久久99亚洲网美利坚合众国| 一本一道久久精品综合| 伊人久久大香线蕉综合热线| 久久99国产精品一区二区| 久久伊人精品青青草原日本| 无码人妻久久一区二区三区免费丨| 久久福利青草精品资源站免费| 国产午夜精品久久久久九九| 亚洲国产精品无码久久| 狠狠色综合网站久久久久久久| 国产99久久久国产精品小说| 色综合久久最新中文字幕| 久久www免费人成看片| 国产午夜精品久久久久九九| 麻豆亚洲AV永久无码精品久久| 久久精品无码一区二区三区免费| 久久夜色精品国产噜噜麻豆 | 91精品国产综合久久精品| 亚洲国产一成久久精品国产成人综合 | 精品国产乱码久久久久软件| 九九久久精品无码专区| 99久久人妻无码精品系列蜜桃| 欧美亚洲国产精品久久|