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

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

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

            轉自http://blog.csdn.net/SeaWave/archive/2006/05/21/747863.aspx

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

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

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

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

            001: /************************************************************************
             002:    
            引用計數基類、及引用計數指針模板類
             003:        
            ----NoSound QQ2591570 可隨意復制、改動、使用、拍磚,概不追究!
             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:     //
            取得對另一指針的控制權
             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++ 基礎

            久久天天躁狠狠躁夜夜av浪潮 | 久久久久免费看成人影片| 久久妇女高潮几次MBA| 色欲av伊人久久大香线蕉影院| 久久精品国产99国产精品导航 | 久久本道伊人久久| 日韩美女18网站久久精品| 伊人久久精品无码二区麻豆| 久久久91精品国产一区二区三区| 精品人妻伦九区久久AAA片69| 精品熟女少妇AV免费久久| 99久久99久久精品国产片果冻| 久久中文字幕精品| 国产精品综合久久第一页| 人妻少妇久久中文字幕一区二区| 日本福利片国产午夜久久| 久久SE精品一区二区| 草草久久久无码国产专区| 亚洲精品无码久久久久sm| 久久有码中文字幕| 91精品婷婷国产综合久久 | 狠狠狠色丁香婷婷综合久久五月| 午夜精品久久久久9999高清| 精品久久香蕉国产线看观看亚洲| 精品久久久无码21p发布| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 久久这里的只有是精品23| 国产精品日韩深夜福利久久 | 综合网日日天干夜夜久久| 久久久久亚洲?V成人无码| 久久97精品久久久久久久不卡| 久久久久人妻一区二区三区| 久久中文字幕无码专区| 国内精品久久久久影院网站| 国产精品久久网| 久久免费视频观看| 2020久久精品国产免费| 青青青国产精品国产精品久久久久| 欧美一区二区三区久久综| 久久精品国产第一区二区三区| 老色鬼久久亚洲AV综合|