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

            doing5552

            記錄每日點(diǎn)滴,不枉人生一世

              C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              73 Posts :: 0 Stories :: 94 Comments :: 0 Trackbacks

            公告

            常用鏈接

            留言簿(24)

            我參與的團(tuán)隊(duì)

            最新隨筆

            搜索

            •  

            積分與排名

            • 積分 - 454873
            • 排名 - 48

            最新隨筆

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            根據(jù)sgi 的STL源碼的二級(jí)分配算法改寫(xiě)的內(nèi)存池分配程序,只要稍微修改就可以實(shí)現(xiàn)共享內(nèi)存方式管理,使用C++標(biāo)準(zhǔn)庫(kù)容器中的map,set,multimap,multiset測(cè)試通過(guò),vector測(cè)試通不過(guò),原因是在內(nèi)存回收的時(shí)候考慮的比較簡(jiǎn)單,vector每次分配內(nèi)存?zhèn)€數(shù)不固定,回收也不固定,這樣的話,程序還需要繼續(xù)完善。

              

            內(nèi)存池管理程序源碼如下:

            以下是引用片段:

            以下是代碼片段:

            #ifndef MY_ALLOCATOR_H_
            #define MY_ALLOCATOR_H_
            #include "stdafx.h"
            #include <limits>
            #include <iostream>
            namespace happyever 
            {
              enum { NODENUMS = 2 };
              union _Obj 
              {
                union _Obj* M_free_list_link;
                char M_client_data[1];    
              } ;
              typedef union _Obj Obj;
              struct _Cookie
              {
                int iShmKey;        /* 共享內(nèi)存鍵值 */
                int iShmID;         /* iShmKey對(duì)應(yīng)的shmid */
                int iSemKey;        /* 鎖信號(hào)鍵值 */
                int iSemID;         /* 鎖信號(hào)標(biāo)識(shí) */
                int iTotalsize;    /* 容器總?cè)萘?*/
                void* pStartall;   /* 共享內(nèi)存自身地址 */
                char* pStartfree;  /* 自由空間的開(kāi)始地址*/
                char* pEndfree;    /* 自由空間的結(jié)束地址*/
                int iUseNum[NODENUMS];
                /*用來(lái)存放free_list中節(jié)點(diǎn)的size*/
                short sFreelistIndex[NODENUMS];
                /*存放分配內(nèi)存節(jié)點(diǎn)的鏈表*/
                Obj* uFreelist[NODENUMS];
              };
              typedef struct _Cookie Cookie;
              //Obj;
              //Cookie;
              static Cookie *pHead = NULL;
              template <class T>
              class MyAlloc 
              {
              private:
                static const int ALIGN = sizeof(Obj);
                int round_up(int bytes);
                int freelist_index(int bytes);
                int freelist_getindex(int bytes);
                char* chunk_alloc(int size, int *nobjs);
                void* refill(int num,int n);
              public:
                // type definitions
                typedef T        value_type;
                typedef T*       pointer;
                typedef const T* const_pointer;
                typedef T&       reference;
                typedef const T& const_reference;
                typedef std::size_t    size_type;
                typedef std::ptrdiff_t difference_type;
                template <class U>
                struct rebind 
                {
                  typedef MyAlloc<U> other;
                };
                pointer address (reference value) const 
                {
                  return &value;
                }
                const_pointer address (const_reference value) const 
                {
                  return &value;
                }
                MyAlloc() throw() 
                {
                  std::cout<<"MyAlloc"<<std::endl;
                }
                MyAlloc(const MyAlloc& x) throw() 
                {
                  std::cout<<"const MyAlloc"<<std::endl;
                }
                template <class U>
                MyAlloc (const MyAlloc<U>& x) throw()
                {
                  std::cout<<"const MyAlloc<U>"<<std::endl;
                }
                ~MyAlloc() throw() 
                {
                  std::cout<<"~MyAlloc"<<std::endl;
                }
                size_type max_size () const throw() 
                {
                  return std::numeric_limits<std::size_t>::max() / sizeof(T);
                }
                //void PrintFreelistAndCookie();
                pointer allocate (size_type num, const void* = 0) 
                {
                  pointer ret = 0;
                  Obj** my_free_list;
                  Obj* result;
                  int index;
                  // print message and allocate memory with global new
                  std::cerr << "allocate " << num << " element(s)"
                    << " of size " << sizeof(T) << std::endl;
                  index = freelist_index(sizeof(T));
                  if(index >= NODENUMS)
                  {
                    return NULL;
                  }
                  my_free_list = pHead->uFreelist + index;
                  //Lock(semid,LOCK_NUM);
                  result = *my_free_list;
                  if (result == 0)
                  {
                    ret = (pointer)refill((int)num, round_up(sizeof(T)));
                  }
                  else
                  {
                    *my_free_list = result->M_free_list_link;
                    ret = (pointer)result;
                  }
                  //UnLock(semid,LOCK_NUM);
                  pHead->iUseNum[index] = pHead->iUseNum[index] + (int)num;
                  if(0 == ret)
                  {
                    std::cerr << "alloc memory fail!" << std::endl;
                    exit(1);
                  }
                  std::cerr << " allocated at: " << (void*)ret << std::endl;
                  PrintFreelistAndCookie();
                  return ret;
                }
                void construct (pointer p, const T& value) 
                {
                  // initialize memory with placement new
                  new((void*)p)T(value);
                }
                void destroy (pointer p) 
                {
                  // destroy objects by calling their destructor
                  p->~T();
                }
                void deallocate (pointer p, size_type num) 
                {
                  Obj** my_free_list;
                  Obj* q ;
                  int index;
                  index = freelist_getindex(sizeof(T));
                  if(index >= NODENUMS)
                  {
                    std::cerr << "deallocate memory fail!" << std::endl;
                    exit(1);
                  }
                  my_free_list = pHead->uFreelist + index;
                  q = (Obj*) p;
                  //Lock(semid,LOCK_NUM);
                  /*這個(gè)地方可能會(huì)有問(wèn)題*/
                  //for(int i=0 ;i<(int)num ; i++)
                  {
                    q->M_free_list_link = *my_free_list;
                    *my_free_list = q;
                  }
                  //UnLock(semid,LOCK_NUM);
                  pHead->iUseNum[index] = pHead->iUseNum[index] - (int)num;
                  
                  std::cerr << "deallocate " << num << " element(s)"
                    << " of size " << sizeof(T)
                    << " at: " << (void*)p << std::endl;
                  PrintFreelistAndCookie();
                }
              };
              template <class T>
              int MyAlloc<T>::round_up(int bytes)
              {
                int i;
                i = bytes;
                if(bytes < ALIGN)
                {
                  i = ALIGN;
                }
                std::cout<<"round_up:bytes="<<bytes<<" , return="<<i<<std::endl;
                return i;
              };
              template <class T>
              int MyAlloc<T>::freelist_index(int bytes)
              {
                int i;
                for(i=0 ; i< NODENUMS ; i++)
                {
                  if(pHead->sFreelistIndex[i] == bytes)
                    break;
                }
                if(i >= NODENUMS)
                {
                  for(i=0 ; i< NODENUMS ; i++)
                  {
                    if(pHead->sFreelistIndex[i] == 0)
                    {
                      pHead->sFreelistIndex[i] = bytes;
                      std::cout<<"freelist_index:bytes="<<bytes<<" , return="<<i<<std::endl;
                      return i;
                    }
                  }
                }
                std::cout<<"freelist_index:bytes="<<bytes<<" , return="<<i<<std::endl;
                return i;
              };
              template <class T>
              int MyAlloc<T>::freelist_getindex(int bytes)
              {
                int i;
                for(i=0 ; i< NODENUMS ; i++)
                {
                  if(pHead->sFreelistIndex[i] == bytes)
                    break;
                }
                std::cout<<"freelist_getindex:bytes="<<bytes<<" , return="<<i<<std::endl;
                return i;
              };
              template <class T>
              char* MyAlloc<T>::chunk_alloc(int size, int *nobjs)
              {
                char* result;
                int counts = *nobjs;
                int total_bytes = size * counts;
                int bytes_left = int(pHead->pEndfree - pHead->pStartfree);
                std::cout<<"chunk_alloc:total_bytes = "<<total_bytes
                  <<",bytes_left = "<<bytes_left<<std::endl;
                if (bytes_left >= total_bytes)
                {
                  result = pHead->pStartfree;
                  pHead->pStartfree += total_bytes;
                  std::cout<<"chunk_alloc:total_bytes = "<<total_bytes
                    <<",result = "<<*result<<",start_free = "<<&(pHead->pStartfree)<<std::endl;
                }
                else if (bytes_left >= size)
                {
                  counts = bytes_left/size;
                  total_bytes = size * counts;
                  result = pHead->pStartfree;
                  pHead->pStartfree += total_bytes;
                  *nobjs = counts;
                  std::cout<<"chunk_alloc:total_bytes = "<<total_bytes<<",nobjs = "<<nobjs
                    <<",result = "<<*result<<",start_free = "<<&(pHead->pStartfree)<<std::endl;
                }
                else
                {
                  /*還需要處理回收其他空閑freelist里面的空間*/
                  result = NULL;
                }
                return(result);
              };
              template <class T>
              void* MyAlloc<T>::refill(int num,int n)
              {
                int counts = num;
                int *nobjs = &counts;
                char* chunk;
                Obj** my_free_list;
                Obj* result;
                Obj* current_obj;
                Obj* next_obj;
                int i;
                chunk = chunk_alloc(n, nobjs);
                if(chunk == NULL)
                {
                  return(chunk);
                }
                counts = *nobjs;
                if (1 == counts)
                {
                  return(chunk);
                }
                my_free_list = pHead->uFreelist + freelist_index(n);
                result = (Obj*)chunk;
                *my_free_list = next_obj = (Obj*)(chunk + n*num);
                for (i = 1; ; i++)
                {
                  current_obj = next_obj;
                  next_obj = (Obj*)((char*)next_obj + n);
                  if (counts - 1 == i)
                  {
                    current_obj->M_free_list_link = 0;
                    break;
                  }
                  else
                  {
                    current_obj->M_free_list_link = next_obj;
                  }
                }
                return(result);
              };
            /*這個(gè)函數(shù)可以改寫(xiě)成自己的共享內(nèi)存分配函數(shù)*/  
            static void InitShm()
              {
                int i,size=1000;
                pHead = (Cookie*)malloc(sizeof(Cookie)+size);
                pHead->iTotalsize = sizeof(Cookie)+size;
                pHead->pStartall  = pHead;
                pHead->pStartfree = (char*)pHead + sizeof(Cookie);
                pHead->pEndfree   = (char*)pHead + pHead->iTotalsize;
                for(i=0 ; i <NODENUMS ; i++)
                {
                  pHead->sFreelistIndex[i]=0;
                  pHead->uFreelist[i]=0;
                  pHead->iUseNum[i]=0;
                }
              }
              static void PrintFreelistAndCookie()
              {
                int i,j;
                Obj* my_free_list;
                std::cout<<"Cookie info :"<<std::endl;
                std::cout<<"sizeof(struct Cookie) = "<<sizeof(Cookie)<<std::endl;
                std::cout<<"Totalsize     = "<<pHead->iTotalsize<<std::endl;
                std::cout<<"UsedSize      = "<<int(pHead->pStartfree-(char*)pHead)<<std::endl;
                std::cout<<"FreepoolSize  = "<<int(pHead->pEndfree - pHead->pStartfree)<<std::endl;
                std::cout<<"Startall      = "<<&(pHead->pStartall)<<std::endl;
                std::cout<<"Startfree     = "<<&(pHead->pStartfree)<<std::endl;
                std::cout<<"Endfree       = "<<&(pHead->pEndfree)<<std::endl;
                std::cout<<"nFreelist info :"<<std::endl;
                for(i=0 ; i<NODENUMS ; i++)
                {
                  j=0;
                  std::cout<<"iUseNum["<<i<<"] = "<<pHead->iUseNum[i]<<std::endl;
                  std::cout<<"FreelistIndex["<<i<<"] = "<<pHead->sFreelistIndex[i]<<std::endl;
                  my_free_list = pHead->uFreelist[i];
                  if(my_free_list->M_client_data != 0)
                  {
                    while(my_free_list->M_client_data != 0)
                    {
                      j++;
                      my_free_list = my_free_list->M_free_list_link;
                    }
                    std::cout<<"free_list["<<i<<"]; node counts="<<j<<std::endl;
                  }
                }
              }
              template <class T1, class T2>
              bool operator== (const MyAlloc<T1>&,const MyAlloc<T2>&) throw() 
              {
                return true;
              }
              template <class T1, class T2>
              bool operator!= (const MyAlloc<T1>&,const MyAlloc<T2>&) throw() 
              {
                return false;
              }
            }
            #endif /*MY_ALLOCATOR_H_*/
            測(cè)試程序的源碼如下:

            // MyStl.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
            //
            #include "stdafx.h"
            #include <map>
            #include <vector>
            #include <string>
            #include <utility>
            #include <iostream>
            #include "MyAlloc.h"
            using namespace std;
            int _tmain(int argc, _TCHAR* argv[])
            {
              happyever ::InitShm();
              multimap<string,int,less<string>,happyever ::MyAlloc<string> > m;
              m.insert(make_pair(string("Harry"), 32));
              m.insert(make_pair(string("Mary"), 59));
              m.insert(make_pair(string("Roger"), 18));
              m.insert(make_pair(string("Nancy"), 37));
              m.insert(make_pair(string("Mary"), 23));
              
              typedef multimap<string,int,less<string>,happyever ::MyAlloc<string> >::iterator Iter;
              for (Iter p = m.begin(); p != m.end(); p++)
              {
                cout << p->first << "," << p->second << endl;
              }
              Iter p = m.find("Harry");
              m.erase(p);
              /*p = m.find("Harry");
              cout << "Harry is: " << p->second << "." << endl;*/

              for (Iter p = m.begin(); p != m.end(); p++)
              {
                cout << p->first << "," << p->second << endl;
              }
              
              return 0;
            }


            以上程序在vs2005,vc6上測(cè)試通過(guò)。使用MinGW編譯的時(shí)候只需要去掉vc的預(yù)編譯頭文件
            #include "stdafx.h"


              即可。

              以上程序只要稍微修改,就可以實(shí)現(xiàn)共享內(nèi)存的管理,可以方便的使用標(biāo)準(zhǔn)庫(kù)提供的容器。加上信號(hào)量的鎖機(jī)制。

              以上為了學(xué)習(xí)而改寫(xiě)的SGI的stl二級(jí)分配算法實(shí)現(xiàn)的。以上代碼存在一定的局限性。我另外完整實(shí)現(xiàn)了共享內(nèi)存管理的STL標(biāo)準(zhǔn)的alloctor程序,使用posix信號(hào)量加鎖。目前應(yīng)用在aix的xlC編譯環(huán)境下。因?yàn)樵创a涉及公司的商業(yè)秘密,所以不能公開(kāi)。但基本上以上源碼已經(jīng)體現(xiàn)了自己管理內(nèi)存的完整思路,供這方面需求的朋友一起學(xué)習(xí)研究用 

            posted on 2010-02-22 00:06 doing5552 閱讀(231) 評(píng)論(0)  編輯 收藏 引用

            只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            国产99久久久国产精品~~牛| 久久99九九国产免费看小说| 伊人久久精品线影院| 人人狠狠综合久久亚洲婷婷| 久久久久久青草大香综合精品| 欧美日韩精品久久久久| 久久久中文字幕日本| 人妻无码久久一区二区三区免费 | 久久丝袜精品中文字幕| 久久精品国产影库免费看| 国产精品成人无码久久久久久| 久久久久久国产精品美女 | 久久久久无码精品国产不卡| 综合久久给合久久狠狠狠97色| 日韩av无码久久精品免费| 热99re久久国超精品首页| 欧美亚洲国产精品久久高清| 99久久精品国产免看国产一区| 日韩精品久久久久久久电影| 亚洲国产成人久久综合一| 尹人香蕉久久99天天拍| 久久99精品国产| 久久午夜羞羞影院免费观看| 一级女性全黄久久生活片免费| 老司机国内精品久久久久| 久久久无码人妻精品无码| 香蕉久久久久久狠狠色| 久久精品国产精品亚洲人人| 久久久九九有精品国产| 久久久久久人妻无码| 2020久久精品亚洲热综合一本| 久久国产综合精品五月天| 久久国产精品久久| 精品综合久久久久久97超人| 久久久久人妻精品一区二区三区 | 一本久久精品一区二区| 久久久久国产视频电影| 久久久久久国产精品免费免费| 久久婷婷五月综合97色| 久久人与动人物a级毛片| 久久久久国产精品嫩草影院|