程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 並行處理之引用計數與狀態的使用

並行處理之引用計數與狀態的使用

編輯:C++入門知識

  在並行處理過程中多線程對同一對象進行操作,而且操作各自獨立,但又需要依賴對象 本身的狀態,如已打開或已登錄等等。這時需要給狀態進行引用計數,以保證操作的有效和 並發性。     為了便於描述, 以<遠程文件系統>中的客戶端連接對象類(TRFConnObj)中部分代碼做為 示例:   // 對象狀態   enum TObjState           {osInactive        = 0,        // 未打開            osClosing         = 1,        // 正在關閉            osOpening         = 2,        // 正在打開            osOpened          = 3};       // 已經打開      // 引用計數加 1   bool TRFConnObj::IncRefCount()   {      // 初始化      bool result = false;         // 操作      Lock();      if (FState == osOpened)      {         FRefCount++;         result = true;      }      Unlock();         // 返回結果      return result;   }      // 引用計數減 1   void TRFConnObj::DecRefCount()   {      Lock();      if (FRefCount > 0)         FRefCount--;      Unlock();   }      // 打開   long TRFConnObj::Open()   {      // 初始化      long  result   = crStateInvalid;      bool  boolNext = false;         // 更改狀態      Lock();      if (FState == osInactive)      {         FState   = osOpening;         boolNext = true;         FRefCount= 0;      }      else if (FState == osOpened)         result   = crSuccess;      Unlock();         // 判斷是否繼續      if (boolNext)      {         // 執行打開         boolNext = false;         result   = DoOpen();            // 更改狀態         Lock();         if (FState != osOpening)            boolNext = true;         else if (result == crSuccess)            FState   = osOpened;         else            FState   = osInactive;         Unlock();            // 判斷是否需要關閉         if (boolNext)         {            // 執行關閉            if (result == crSuccess)            {               DoClose(true);               result = crFailure;            }               // 更改狀態(不需要加鎖)            FState = osInactive;         }      }         // 返回結果      return result;   }      // 關閉   void TRFConnObj::Close(bool ANeedWait)   {      // 初始化      bool boolNext  = false;      bool boolWait  = false;         // 更改狀態      Lock();      if (FState == osOpened)      {         FState   = osClosing;         boolNext = true;      }      else if (FState == osOpening)      {         FState   = osClosing;         boolWait = true;      }      else if (FState == osClosing)         boolWait = ANeedWait;      Unlock();         // 判斷是否等待      if (boolWait)      {         // 等待 Close 結束         while (FState == osClosing)            Sleep(15);      }      else if (boolNext)      {         // 執行關閉         DoClose(true);            // 更改狀態(不需要加鎖)         FState = osInactive;      }   }      // 並行操作的方法   long TRFConnObj::(...)   {      // 初始化      long result = crStateInvalid;         // 引用計數加 1      if (IncRefCount())      {         // 操作         // ??? ... ...            // 引用計數減 1         DecRefCount();      }         // 返回結果      return result;   }         可以把 Open 和 Close 方法理解為打開和關閉並行處理之門,只有 Open 之後才有效。 當調用 Close 方法時,若還有其它線程正在操作相關方法,則會等待操作完成後才能關閉, 若已調用 Close 方法且狀態為 osClosing 且其它線程開始操作相關方法時,則會直接返回 狀態無效,並拒之門外。      對象狀態和引用計數配合使用會提高事件處理的並發性,且不會在邊界狀態時導致異常 發生,同時還可以保證系統的並發性能。在服務器程序的開發中會常用到引用計數和狀態, 若完全理解 Open 和 Close 中狀態處理,則有助於靈活運用到並發性高的軟件開發中。  <遠程文件系統>提供完整源碼,下載地址如下:     遠程文件系統服務器源碼[http://download.csdn.net/detail/kyee/5109478]     遠程文件系統客戶端源碼[http://download.csdn.net/detail/kyee/5109484]     服務器和客戶端相關接口[http://download.csdn.net/detail/kyee/5109491] 客戶端連接對象類(TRFConnObj)部分代碼如下:   // 返回值及錯誤碼   enum TRFCResult           {crSuccess         =  1,       // 成功            crFailure         =  0,       // 失敗            crUnknown         = -1,       // 未知錯誤            crNotExist        = -2,       // 不存在(如: AConnObj)            crNotStart        = -3,       // 服務器未啟動            crNotConnect      = -4,       // 連接未打開            crNonsupport      = -5,       // 不支持            crVersion         = -6,       // 版本太低            crPassword        = -7,       // 密碼錯誤            crIsExisted       = -8,       // 已存在            crIsIllegal       = -9,       // 不合法            crAttrInvalid     = -10,      // 屬性無效            crStateInvalid    = -11,      // 狀態無效            crHandleInvalid   = -12,      // 句柄無效            crAccessIllegal   = -13};     // 存取非法      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~      /* TRFConnObj - 客戶端連接對象類 */      class TRFConnObj   {   public:      TRFConnObj(TRFConnEvent* AEventObj  = NULL, const char* AHost     = NULL,                         long  APort      = 0,    const char* APassword = NULL);      virtual ~TRFConnObj();         // 屬性      void*             Data() const         { return FData; }      TRCConnection*    ConnObj() const      { return FConnObj; }      TRFConnEvent*     EventObj() const     { return FEventObj; }      Longword          CallTimeout() const  { return FCallTimeout; }         TObjState         State() const        { return FState; }         KYString          RFVersion() const    { return FRFInfo.Version; }      TDateTime         RFStartTime() const  { return FRFInfo.StartTime; }      TDateTime         RFDateTime();         // 設置屬性      void              SetData(void* AData) { FData = AData; }      void              SetCallTimeout(Longword ATimeout);         // 打開/關閉連接      long              Open();      void              Close(bool ANeedWait = false);         // 讀取/設置文件屬性      long              GetFileAttr(const char* AFileName, long* Attrib);      long              SetFileAttr(const char* AFileName, long  Attrib);         // 文件存在/刪除/移動文件或目錄      long              FileExisted(const char* AFileName);      long              DeleteFile(const char* AFileName);      long              MoveFile(const char* AOldName, const char* ANewName);         // 目錄存在/創建/刪除      long              DirExisted(const char* APathName);      long              CreateDir(const char* APathName, bool AForced = false);      long              RemoveDir(const char* APathName, bool AForced = false);         // 磁盤操作相關函數      long              DriveType(const char* ADrive, long* AType);      long              DiskSpace(const char* APath, __int64* ATotalSpace,                                                     __int64* AFreeSpace);      protected:      // 狀態鎖      void              Lock() const         { FLock->Enter(); }      void              Unlock() const       { FLock->Leave(); }         // 對象次數增減      long              IncObjTimes()        { return InterlockedIncrement(&FObjTimes); }      long              DecObjTimes()        { return InterlockedDecrement(&FObjTimes); }         // 引用計數增減      bool              IncRefCount_Valid();      bool              IncRefCount();      void              DecRefCount();         // 讀取 RF 的信息      void              GetRFInfo();      void              GetRFDateTime();         // 存取 RF 屬性方法      long              GetRFInt(long Attrib, long& AValue);      long              GetRFStr(long Attrib, KYString& AValue);      long              SetRFInt(long Attrib, long AValue);      long              SetRFStr(long Attrib, const char* AValue, long ALen);      private:      // 執行初始化/釋放      void              DoInit();      void              DoFreeing()          { FEventObj->DoFreeing(this); }         // 執行打開/關閉      long              DoOpen();      void              DoClose(bool ANeedClose);         // 執行斷開連接      void              DoDisconnect();      void              CallOnDisconnect();         // 執行 RC 事件的回調方法      void              DoRecvData(const void* AData, long ASize);      private:      void*             FData;               // 自定義數據      TKYCritSect*      FLock;               // 狀態鎖      TRCConnection*    FConnObj;            // RC 連接對象      TRFConnEvent*     FEventObj;           // 事件對象         TObjState         FState;              // 狀態      long              FObjTimes;           // 對象次數      long              FRefCount;           // 引用計數      Longword          FCallTimeout;        // 調用超時時長(毫秒)         TRFInfo           FRFInfo;             // 存儲服務器信息      Longword          FLastTick;           // 讀取最後一次 RFDateTime 的 tick 值      TDateTime         FDeltaTime;          // 存儲服務器的當前時間差值         TRFCOnDisconnect  FOnDisconnect;       // OnDisconnect 回調事件函數      private:      // RC 連接的回調函數      static void __stdcall   _DoRCCallback(long AConnID, long AEvent,                                            long ACmdID,  long AReturn);      static void __stdcall   _DoRCRecvData(long AConnID, long ASize, const void* AData);   };  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved