支持多线程,自我感觉良好,不多说明,看代码就明白了. 如果这个代码有什么问题,一定要告诉我. 推荐编译平台VS2005 提示:点击下面的小字"expand source"展开代码. // // MemPool.h // My Bolg:http://blog.csdn.net/sidyhe #pragma once #include <Windows.h> #define POOLAPI __fastcall /* 一个MEMORY_BLOCK的内存大小是SIZE_BLOCK_BYTE 分成COUNT_ALL_BLOCK个块,每个块的大小是SIZE_ONE_BLOCK 当用户申请的内存大小超过SIZE_BLOCK_BYTE时,使用系统函数来分配 */ #define SIZE_ONE_BLOCK 0x00000100 //内存颗粒度(256Byte) #define COUNT_ALL_BLOCK 0x000007FD //分成几部分 #define SIZE_BLOCK_BYTE (SIZE_ONE_BLOCK * COUNT_ALL_BLOCK) //默认内存分配大小(511KB) typedef struct _MEMPOOL_NODE //记录使用及剩余量的链表 { DWORD Phy_Start; //起始偏移(相对于内存块) DWORD dwAllocateSize; //分配内存大小 _MEMPOOL_NODE *pNext; //指向下一节点 BYTE bUsed; //是否使用了 }MEMPOOL_NODE, *PMEMPOOL_NODE; typedef struct _MEMORY_BLOCK //内存块数据结构,双向链表 { PVOID pAddress; //内存地址 DWORD dwRemain; //尚未使用的内存空间大小 CRITICAL_SECTION m_Critical; //每一个内存块分配一个临界 PMEMPOOL_NODE pLink_Allocated;//已分配内存的链表 PMEMPOOL_NODE pLink_Free; //尚未使用内存的链表 _MEMORY_BLOCK *pPrev; //指向上一节点 _MEMORY_BLOCK *pNext; //指向下一节点 _MEMPOOL_NODE NodeReserved[COUNT_ALL_BLOCK];//存放节点,免得频繁申请释放内存 }MEMORY_BLOCK, *PMEMORY_BLOCK; class CMemPool { public: CMemPool(void); ~CMemPool(void); PVOID POOLAPI Allocate(DWORD dwSize); //分配内存,失败返回NULL BOOL POOLAPI Free(PVOID pAddress); //释放内存,成功返回非0 #ifdef _DEBUG void PrintLink(); #endif private: DWORD m_dwCount; //计数器(正在操作的线程数) HANDLE m_Event_Pause; //暂停信号,用于清理内存 HANDLE m_Sign_Kill; HANDLE m_hClear; //清理线程 PMEMORY_BLOCK m_pBlockHeader; //头结点 CRITICAL_SECTION m_CS_Block; //修改BLOCK链表的临界 void POOLAPI InitializeBlock(PMEMORY_BLOCK pBlock); void POOLAPI UnInitializeBlock(PMEMORY_BLOCK pBlock); static DWORD WINAPI ClearThread(LPVOID pData); void POOLAPI InsertNode(PMEMORY_BLOCK pBlock, PMEMPOOL_NODE pNode, BOOL isFreeLink); void POOLAPI DeleteNode(PMEMORY_BLOCK pBlock, PMEMPOOL_NODE pNode, BOOL isFreeLink); void POOLAPI CombineNode(PMEMORY_BLOCK pBlock);//合并空余空间 PVOID POOLAPI AllocByBlock(PMEMORY_BLOCK pBlock, DWORD dwSize);//根据BLOCK分配空间 PMEMPOOL_NODE POOLAPI FindFreeNode(PMEMORY_BLOCK pBlock); }; // // MemPool.cpp // My Bolg:http://blog.csdn.net/sidyhe #include "MemPool.h" #ifdef _DEBUG #include <stdio.h> #endif CMemPool::CMemPool(void) { m_dwCount = 0; m_pBlockHeader = NULL; InitializeCriticalSection(&m_CS_Block); m_Event_Pause = CreateEvent(NULL, TRUE, TRUE, NULL);//匿名,手动置信号,初始有信号 m_Sign_Kill = CreateEvent(NULL, TRUE, FALSE, NULL); m_hClear = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ClearThread, this, NULL, NULL); } CMemPool::~CMemPool(void) { PMEMORY_BLOCK pBlock, pBlockTmp; SetEvent(m_Sign_Kill); WaitForSingleObject(m_hClear, INFINITE); CloseHandle(m_hClear); CloseHandle(m_Sign_Kill); CloseHandle(m_Event_Pause); DeleteCriticalSection(&m_CS_Block); //回收所有释放的资源 for (pBlock = m_pBlockHeader; pBlock; pBlock = pBlockTmp) { pBlockTmp = pBlock->pNext; UnInitializeBlock(pBlock); } } void CMemPool::InitializeBlock(PMEMORY_BLOCK pBlock) { ZeroMemory(pBlock, sizeof(MEMORY_BLOCK)); InitializeCriticalSection(&pBlock->m_Critical); pBlock->pAddress = VirtualAllocEx(INVALID_HANDLE_VALUE, NULL, SIZE_BLOCK_BYTE, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); pBlock->pLink_Free = &pBlock->NodeReserved[0]; pBlock->pLink_Free->bUsed = TRUE; pBlock->pLink_Free->Phy_Start = 0; pBlock->pLink_Free->dwAllocateSize = SIZE_BLOCK_BYTE; pBlock->dwRemain = SIZE_BLOCK_BYTE; } void CMemPool::UnInitializeBlock(PMEMORY_BLOCK pBlock) { if (pBlock->dwRemain < SIZE_BLOCK_BYTE) return; if (m_pBlockHeader == pBlock)//是头结点 { m_pBlockHeader = m_pBlockHeader->pNext; if (m_pBlockHeader) m_pBlockHeader->pPrev = NULL; } else//不是头结点 { pBlock->pPrev->pNext = pBlock->pNext; if (pBlock->pPrev->pNext) pBlock->pNext->pPrev = pBlock->pPrev; } DeleteCriticalSection(&pBlock->m_Critical); VirtualFreeEx(INVALID_HANDLE_VALUE, pBlock->pAddress, 0, MEM_RELEASE); VirtualFreeEx(INVALID_HANDLE_VALUE, pBlock, 0, MEM_RELEASE); return; } void CMemPool::InsertNode(PMEMORY_BLOCK pBlock, PMEMPOOL_NODE pNode, BOOL isFreeLink) { PMEMPOOL_NODE pCurrNode; pNode->bUsed = TRUE; if (isFreeLink) { if (pBlock->pLink_Free) { pCurrNode = pBlock->pLink_Free; if (pCurrNode->Phy_Start > pNode->Phy_Start)//NODE最小 { pNode->pNext = pBlock->pLink_Free; pBlock->pLink_Free = pNode; return; } } else//头结点NULL { pBlock->pLink_Free = pNode; pNode->pNext = NULL; return; } } else//已分配链表 { if (pBlock->pLink_Allocated) { pCurrNode = pBlock->pLink_Allocated; if (pNode->Phy_Start < pCurrNode->Phy_Start)//NODE最小 { pNode->pNext = pBlock->pLink_Allocated; pBlock->pLink_Free = pNode; return; } } else//头结点NULL { pBlock->pLink_Allocated = pNode; pNode->pNext = NULL; return; } } for (;pCurrNode->pNext; pCurrNode = pCurrNode->pNext) { if (pNode->Phy_Start > pCurrNode->Phy_Start && pNode->Phy_Start < pCurrNode->pNext->Phy_Start)//大于当前的小于下一个 { pNode->pNext = pCurrNode->pNext; pCurrNode->pNext = pNode; return; } } //pNode最大 pCurrNode->pNext = pNode; pNode->pNext = NULL; return; } void CMemPool::DeleteNode(PMEMORY_BLOCK pBlock, PMEMPOOL_NODE pNode, BOOL isFreeLink) { PMEMPOOL_NODE pCurrNode; if (isFreeLink) { if (!pBlock->pLink_Free) return; pCurrNode = pBlock->pLink_Free; if (pCurrNode == pNode)//是头结点 { pBlock->pLink_Free = pCurrNode->pNext; pNode->bUsed = FALSE; return; } } else { if (!pBlock->pLink_Allocated) return; pCurrNode = pBlock->pLink_Allocated; if (pCurrNode == pNode)//是头结点 { pBlock->pLink_Allocated = pCurrNode->pNext; pNode->bUsed = FALSE; return; } } for (; pCurrNode->pNext; pCurrNode = pCurrNode->pNext) { if (pCurrNode->pNext == pNode) { pCurrNode->pNext = pCurrNode->pNext->pNext; pNode->bUsed = FALSE; break;//for } } //难道都没找到??? return; } PMEMPOOL_NODE CMemPool::FindFreeNode(PMEMORY_BLOCK pBlock) { PMEMPOOL_NODE pRet = NULL; for (pRet = pBlock->NodeReserved; pRet; pRet++) { if (pRet->bUsed == FALSE) break; } ZeroMemory(pRet, sizeof(MEMPOOL_NODE)); return pRet; } void CMemPool::CombineNode(PMEMORY_BLOCK pBlock) { PMEMPOOL_NODE pNode = pBlock->pLink_Free; while (pNode && pNode->pNext) { if (pNode->Phy_Start + pNode->dwAllocateSize == pNode->pNext->Phy_Start) { pNode->dwAllocateSize += pNode->pNext->dwAllocateSize; pNode->pNext->bUsed = FALSE; pNode->pNext = pNode->pNext->pNext; } else { pNode = pNode->pNext; } } } PVOID CMemPool::AllocByBlock(PMEMORY_BLOCK pBlock, DWORD dwSize) { PVOID pRet = NULL; PMEMPOOL_NODE pNode, pNewNode; for (pNode = pBlock->pLink_Free; pNode; pNode = pNode->pNext) { if (pNode->dwAllocateSize >= dwSize) { if (pNode->dwAllocateSize == dwSize) { DeleteNode(pBlock, pNode, TRUE); InsertNode(pBlock, pNode, FALSE); pRet = (PVOID)( (DWORD)pBlock->pAddress + pNode->Phy_Start ); pBlock->dwRemain -= dwSize; break;//for } else// > { pNewNode = FindFreeNode(pBlock); pNewNode->Phy_Start = pNode->Phy_Start; pNode->Phy_Start += dwSize; pNewNode->dwAllocateSize = dwSize; pNode->dwAllocateSize -= dwSize; InsertNode(pBlock, pNewNode, FALSE); pRet = (PVOID)( (ULONG)pBlock->pAddress + pNewNode->Phy_Start ); pBlock->dwRemain -= dwSize; break;//for } } } if (pRet) ZeroMemory(pRet, dwSize); return pRet; } PVOID CMemPool::Allocate(DWORD dwSize) { PVOID pRet = NULL; DWORD dwAllocSize; PMEMORY_BLOCK pBlock; if (dwSize <= 0) return pRet; if (dwSize > SIZE_BLOCK_BYTE) return VirtualAllocEx(INVALID_HANDLE_VALUE, NULL, dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); InterlockedExchangeAdd((PLONG)&m_dwCount, 1);//计数器 + 1 if (WaitForSingleObject(m_Event_Pause, 1) != WAIT_OBJECT_0)//正在整理内存则暂停 { InterlockedExchangeAdd((PLONG)&m_dwCount, -1);//计数器 - 1 WaitForSingleObject(m_Event_Pause, INFINITE); InterlockedExchangeAdd((PLONG)&m_dwCount, 1);//计数器 + 1 } dwAllocSize = dwSize % SIZE_ONE_BLOCK ? dwSize / SIZE_ONE_BLOCK + 1 : dwSize / SIZE_ONE_BLOCK;//SIZE_ONE_BLOCK取整 dwAllocSize *= SIZE_ONE_BLOCK; for (pBlock = m_pBlockHeader; pBlock; pBlock = pBlock->pNext) { if (pBlock->dwRemain >= dwAllocSize) { EnterCriticalSection(&pBlock->m_Critical); pRet = AllocByBlock(pBlock, dwAllocSize); LeaveCriticalSection(&pBlock->m_Critical); } } if (pRet == NULL)//都没有符合的,新建个BLOCK,继续 { pBlock = (PMEMORY_BLOCK)VirtualAllocEx(INVALID_HANDLE_VALUE, NULL, sizeof(MEMORY_BLOCK), MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); InitializeBlock(pBlock); EnterCriticalSection(&m_CS_Block); if (m_pBlockHeader)//头前插 { pBlock->pNext = m_pBlockHeader; m_pBlockHeader->pPrev = pBlock; m_pBlockHeader = pBlock; } else//头结点NULL { m_pBlockHeader = pBlock; } LeaveCriticalSection(&m_CS_Block); EnterCriticalSection(&pBlock->m_Critical); pRet = AllocByBlock(pBlock, dwAllocSize);//不能再失败了吧 LeaveCriticalSection(&pBlock->m_Critical); } InterlockedExchangeAdd((PLONG)&m_dwCount, -1);//计数器 - 1 return pRet; } BOOL CMemPool::Free(PVOID pAddress) { BOOL bRet = FALSE; PMEMORY_BLOCK pBlock; PMEMPOOL_NODE pNode; DWORD dwPhy; if (pAddress == NULL) return bRet; InterlockedExchangeAdd((PLONG)&m_dwCount, 1);//计数器 + 1 if (WaitForSingleObject(m_Event_Pause, 1) != WAIT_OBJECT_0)//正在整理内存则暂停 { InterlockedExchangeAdd((PLONG)&m_dwCount, -1);//计数器 - 1 WaitForSingleObject(m_Event_Pause, INFINITE); InterlockedExchangeAdd((PLONG)&m_dwCount, 1);//计数器 + 1 } EnterCriticalSection(&m_CS_Block); for (pBlock = m_pBlockHeader; pBlock; pBlock = pBlock->pNext) { if ((ULONG)pBlock->pAddress <= (ULONG)pAddress && (ULONG)pBlock->pAddress + SIZE_BLOCK_BYTE > (ULONG)pAddress) break; } LeaveCriticalSection(&m_CS_Block); if (pBlock)//找到了这个BLOCK { dwPhy = (ULONG)pAddress - (ULONG)pBlock->pAddress; EnterCriticalSection(&pBlock->m_Critical); for (pNode = pBlock->pLink_Allocated; pNode; pNode = pNode->pNext) { if (pNode->Phy_Start == dwPhy) break; } if (pNode)//找到该节点了 { pBlock->dwRemain += pNode->dwAllocateSize; DeleteNode(pBlock, pNode, FALSE); InsertNode(pBlock, pNode, TRUE); //整合空闲内存 CombineNode(pBlock); bRet = TRUE; } LeaveCriticalSection(&pBlock->m_Critical); } else { bRet = VirtualFreeEx(INVALID_HANDLE_VALUE, pAddress, 0, MEM_RELEASE);//都找不到,应该是这个了 } InterlockedExchangeAdd((PLONG)&m_dwCount, -1);//计数器 - 1 return bRet; } DWORD WINAPI CMemPool::ClearThread(LPVOID pData) { DWORD dwCount; PMEMORY_BLOCK pBlock, pBlockTmp; CMemPool *pThis = (CMemPool *)pData; while (1) { #ifdef _DEBUG for (dwCount = 0; dwCount < 10 * 5; dwCount++)//5秒 #else for (dwCount = 0; dwCount < 10 * 60 * 10; dwCount++)//10分钟 #endif { if (WaitForSingleObject(pThis->m_Sign_Kill, 100) == WAIT_OBJECT_0) return 0;//有退出信号则EXIT } ResetEvent(pThis->m_Event_Pause); while (InterlockedExchangeAdd((PLONG)&pThis->m_dwCount, 0)) Sleep(0); for (pBlock = pThis->m_pBlockHeader; pBlock; pBlock = pBlockTmp) { pBlockTmp = pBlock->pNext; pThis->UnInitializeBlock(pBlock); } SetEvent(pThis->m_Event_Pause); } return -1; } / // Debug #ifdef _DEBUG void CMemPool::PrintLink() { PMEMORY_BLOCK pBlock; PMEMPOOL_NODE pNode; EnterCriticalSection(&m_CS_Block); for (pBlock = m_pBlockHeader; pBlock; pBlock = pBlock->pNext) { printf("[BLOCK]基地址:%08X 剩余大小:%08X/n", pBlock->pAddress, pBlock->dwRemain); for (pNode = pBlock->pLink_Allocated; pNode; pNode = pNode->pNext) { printf("[已分配] 起始偏移:%08X 占用大小:%08X/n", pNode->Phy_Start, pNode->dwAllocateSize); } for (pNode = pBlock->pLink_Free; pNode; pNode = pNode->pNext) { printf("[空闲中] 起始偏移:%08X 占用大小:%08X/n", pNode->Phy_Start, pNode->dwAllocateSize); } } LeaveCriticalSection(&m_CS_Block); } #endif