固定尺寸記憶體塊的緩衝隊列類及C++實現原始碼

來源:互聯網
上載者:User

標籤:efi   推斷   簡單   ext   3.0.0   style   清除   sim   使用   

--------------------------------------------------------------------------------
標題: 固定尺寸記憶體塊的緩衝隊列類及實現原始碼
作者: 葉飛虎
日期: 2014.10.21
--------------------------------------------------------------------------------

    在一般的線性操作應用中(如: 接收緩衝區), 可能須要頻繁分配和釋放記憶體塊, 頻繁操
作會給系統帶來非常大開銷, 怎樣降低系統開銷? 通過拉大分配和釋放之間間距來降低操作的
頻度, 從而達到降低系統開銷。

    拉大分配和釋放之間間距的方法有非常多, 能夠通過大記憶體塊自己管理, 也能夠通過記憶體
塊緩衝隊列。

本文著重講記憶體塊緩衝隊列, 涉及隊列就會考慮到無鎖進出隊列, 即進隊列和
出隊列在二個線程中能夠同一時候操作。

無鎖隊列的實現方法有非常多, 有數組方式的環形無鎖隊
列, 也有連結方式的無鎖隊列。

數組方式在隊列容量確定時比較適合, 而連結方式更適合於
隊列容量可變情況, 適用性更好。

    數組方式無鎖隊列見我的博文 <在一讀一寫限制下,無鎖環形隊列怎樣實現?>
    連結方式無鎖隊列見我的博文 <一讀一寫情況下。無鎖隊列怎樣實現?>

    本文講的緩衝隊列為連結方式, 連結方式一般通過預分配一個結點作為接力點來實現無
鎖隊列, 長處是實現簡單, 缺點是浪費一個結點的記憶體, 當結點記憶體塊尺寸較大時浪費就大
了。怎樣不浪費一個結點記憶體的連結方式無鎖隊列? 當隊列中僅僅有一個結點時, 本緩衝隊列
中使用了原子鎖進行操作, 這是一種平衡策略, 若讀者有更好方法最好還是告之中的一個下!

    固定尺寸記憶體塊的緩衝隊列類(TKYCache)原始碼例如以下:

// =======================================// Unit   : 固定尺寸的記憶體塊緩衝// Version: 3.0.0.0 (build 2014.10.21)// Author : Kyee Ye// Email  : kyee_ye(at)126.com// Copyright (C) Kyee workroom// =======================================#ifndef _KYCache_H_#define _KYCache_H_#include "KYObject.h"// KYLib 2.0 開始使用 KYLib 命名空間namespace KYLib{// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/* TKYCache - 固定尺寸的記憶體塊緩衝類 */// 注:// 1. 為了多線程存取安全, New 和 Delete 分屬二個線程時能夠同一時候操作而不須要加鎖,//    但多線程 New 時必須用鎖控制, 多線程 Delete 時必須用鎖控制!// 2. 此緩衝類一般應用於線性操作的類中, 以降低頻繁分配和釋放記憶體的緩衝使用.class TKYCache{private:   // 記憶體塊的連結   typedef struct   {      void*       Self;                // 記憶體塊所屬對象      void*       Next;                // 下一塊   } TLink, *PLink;public:   // 建構函式   // 1. ABlockSize  記憶體塊的固定尺寸, 取值範圍: [0x40..0x40000000]   // 2. AMaxCount   記憶體塊緩衝的最大個數   TKYCache(long ABlockSize = 1024, long AMaxCount = 256);   virtual ~TKYCache();   // 屬性   long           Count() const        { return FPushCount - FPopCount; }   long           MaxCount() const     { return FMaxCount; }   // default: AMaxCount   long           BlockSize() const    { return FBlockSize; }  // default: ABlockSize   // 設定記憶體塊緩衝的最大個數   void           SetMaxCount(long AMaxCount)                  { FMaxCount = (AMaxCount >= 0) ? AMaxCount : 0; }   // 分配固定尺寸的記憶體塊   void*          New()                  {                     TLink* pItem = DoNew();                     return (pItem != NULL) ?

(char*)pItem + sizeof(TLink) : NULL; } // 釋放固定尺寸的記憶體塊 void Delete(void* ABlock) { if (ABlock != NULL) { TLink* pItem = (TLink*)((char*)ABlock - sizeof(TLink)); if (pItem->Self == this) DoDelete(pItem); } }private: // 運行分配/釋放帶連結的記憶體塊 TLink* DoNew(); void DoDelete(TLink* ALink); // 運行清除緩衝隊列 void DoClear(TLink* AHead);private: TLink* FHead; // 緩衝的頭連結 TLink* FTail; // 緩衝的尾連結 long FFlag; // 緩衝隊列標誌 long FMaxCount; // 緩衝最大個數 long FBlockSize; // 記憶體塊的尺寸 Longword FPushCount; // 壓入緩衝計數 Longword FPopCount; // 彈出緩衝計數};}#endif


 

// =======================================// Unit   : 固定尺寸的記憶體塊緩衝// Version: 3.0.0.0 (build 2014.10.21)// Author : Kyee Ye// Email  : kyee_ye(at)126.com// Copyright (C) Kyee workroom// =======================================#include <malloc.h>#include "KYCache.h"// KYLib 2.0 開始使用 KYLib 命名空間namespace KYLib{// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/* TKYCache - 固定尺寸的記憶體塊緩衝類 */// ---------------- 建構函式和解構函式 ----------------// 建構函式TKYCache::TKYCache(long ABlockSize, long AMaxCount){   // 初始化   FHead       = NULL;   FTail       = NULL;   FFlag       = 0;   FPushCount  = 0;   FPopCount   = 0;   // 設定緩衝最大個數   FMaxCount   = (AMaxCount >= 0) ? AMaxCount : 0;   // 設定記憶體塊的尺寸   if (ABlockSize <= 0x40)      FBlockSize  = 0x40;   else if (ABlockSize <= 0x40000000)      FBlockSize  = ABlockSize;   else      FBlockSize  = 0x40000000;}// 解構函式TKYCache::~TKYCache(){   // 運行清除緩衝隊列   if (FPopCount != FPushCount)   {      FPopCount   = FPushCount;      DoClear(FHead);   }}// ---------------- 私人函數 ----------------// 運行分配帶連結的記憶體塊TKYCache::TLink* TKYCache::DoNew(){   // 初始化   TLink* result = NULL;   // 推斷緩衝隊列是否為空白   if (FPopCount == FPushCount)      result = (TLink*)malloc(sizeof(TLink) + FBlockSize);   else if (FPushCount - FPopCount != 1)   {      // 取第一項, 而且計數加 1      result = FHead;      FHead  = (TLink*)result->Next;      FPopCount++;   }   else   {      // 取第一項      result = FHead;      // 推斷是否須要等待, 防止 DoDelete 衝突      if (InterlockedIncrement(&FFlag) == 1)      {         FPopCount++;         if (FPopCount == FPushCount)         {            FHead  = NULL;            FTail  = NULL;         }         InterlockedDecrement(&FFlag);      }      else      {         FPopCount++;         InterlockedDecrement(&FFlag);         // 迴圈等待 FPushCount 變化         while (FPopCount == FPushCount)            Sleep(1);      }      // 改動緩衝的頭連結      if (result->Next != NULL)         FHead = (TLink*)result->Next;   }   // 初始化連結項   if (result != NULL)   {      result->Self = this;      result->Next = NULL;   }   // 返回結果   return result;}// 運行釋放帶連結的記憶體塊void TKYCache::DoDelete(TLink* ALink){   // 推斷是否已滿   if (FPushCount - FPopCount >= (Longword)FMaxCount)      free(ALink);   else   {      // 置空      ALink->Next = NULL;      // 引用計數加 1, 若不等於 1 則等待 DoNew 變成 1      if (InterlockedIncrement(&FFlag) != 1)         while (FFlag != 1)            Sleep(0);      // 推斷是否為第一項      if (FTail == NULL)      {         FTail       = ALink;         FHead       = ALink;      }      else      {         FTail->Next = ALink;         FTail       = ALink;      }      // 計數加 1, 且引用計數減 1(注: 順序不能改, 否則可能會導致DoNew死迴圈)      FPushCount++;      InterlockedDecrement(&FFlag);   }}// 運行清除緩衝隊列void TKYCache::DoClear(TLink* AHead){   // 初始化   void* pCurr;   // 迴圈釋放   while (AHead != NULL)   {      pCurr = AHead;      AHead = (TLink*)AHead->Next;      // 釋放      free(pCurr);   }}}

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

固定尺寸記憶體塊的緩衝隊列類及C++實現原始碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.