博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c 单线程内存池实现
阅读量:4055 次
发布时间:2019-05-25

本文共 12970 字,大约阅读时间需要 43 分钟。

本文实现了单线程内存池,其原理是根据里《C++应用程序性能优化》 所描述的那样,本文只贴实现代码,具体详情,参考此书。

内存池头文件

/* * * Copyright (c)  * * All rights reserved. * * * * 文件名称:memory_pool.h * * 文件标识:无 * * 摘要:单线程内存池调皮文件 * * * * 当前版本:1.0 * * 作者:lishaozhe * * 完成日期:2014年6月12日 * * * * 取代版本: * * 原作者: * * 完成日期: * **/#ifdef MEMORY_POOL_H#else#define MEMORY_POOL_H#include 
#include
#include
#define USHORT unsigned short #define ULONG unsigned long#define MEMPOOL_ALIGNMENT 8 /*将大于4个字节的大小_n_unit_size往上"取整到"大于_n_unit_size的最小的MEMPOOL_ ALIGNMENT的倍数(前提是MEMPOOL_ALIGNMENT为2的倍数)。如_n_unit_size为11 时,MEMPOOL_ALIGNMENT为8,n_unit_size为16;MEMPOOL_ALIGNMENT为4,n_unit_size为 12;MEMPOOL_ALIGNMENT为2,n_unit_size为12,依次类推。*/typedef struct memory_block{ ULONG n_size; /*为块内所有内存分配单元的大小(注意,并不包括MemoryBlock结构体的大小)*/ USHORT n_free; /*n_free记录这个内存块中还有多少个自由分配单元*/ USHORT n_first; /*n_first则记录下一个可供分配的单元的编号*/ USHORT n_dummy_align; /*未用*/ struct memory_block *p_next; /*链表中下一个memory_block_s*/ char a_data[1]; /*数据域开始地址*/}memory_block_s, * memory_block_p;typedef struct memory_pool{ memory_block_p p_block; /*memory_block_s块指针,链表头指针*/ USHORT block_number; /*已经存在的内存块个数*/ USHORT n_unit_size; /*固定内存分配大小*/ USHORT n_init_size; /*初始时memory_block_s中内存单元个数*/ USHORT n_grow_size; /*增加分配内存单元个数*/}memory_pool_s, * memory_pool_p;/*************************************************Function: memory_pool_init()Description: 内存池初始化函数,只初始化memory_pool_s结构提,并没有分配内存块空间 Input: _n_unit_size:内存单元大小 _n_init_size:初次分配内存块时内存单元分配时的个数 _n_grow_size:增长分配内存块时,内存单元的个数Output: 无Return: 返回一个memory_pool_p的指针Others: 无*************************************************/memory_pool_p memory_pool_init(USHORT _n_unit_size, USHORT _n_init_size, USHORT _n_grow_size );/*************************************************Function: memory_pool_alloc()Description: 分配一块固定大小的内存,大小等于你在memory_pool_init()中传入的_n_unit_size的大小Input: pool:内存池指针Output: 无Return: 返回一个固定大小内存单元的指针Others: 无*************************************************/ void* memory_pool_alloc(memory_pool_p pool);/*************************************************Function: memory_pool_free()Description: 释放分配的内存 Input: pool:内存池指针 pFree:待释放内存的指针Output: 无Return: 无Others: 无*************************************************/void memory_pool_free( memory_pool_p pool, void *pFree );/*************************************************Function: memory_pool_destroy()Description: 销毁内存池 Input: pool:内存池指针Output: 无Return: 无Others: 无*************************************************/ void memory_pool_destroy(memory_pool_p pool);/*************************************************Function: memory_pool_debug()Description: 打印内存池信息,以及内存块的信息Input: pool:内存池指针Output: 输出内存池信息,以及内存块的信息Return: 无Others: 无*************************************************/void memory_pool_debug(memory_pool_p pool);#endif

内存池实现文件

/* * * Copyright (c)  * * All rights reserved. * * * * 文件名称:memory_pool.c * * 文件标识:无 * * 摘要:单线程内存池实现 * * * * 当前版本:1.0 * * 作者:lishaozhe * * 完成日期:2014年6月12日 * * * * 取代版本: * * 原作者: * * 完成日期: * **/#include 
#include
#include
#include "memory_pool.h"#include "mydebug.h"/*************************************************Function: memory_pool_init()Description: 内存池初始化函数,只初始化memory_pool_s结构提,并没有分配内存块空间 Input: _n_unit_size:内存单元大小 _n_init_size:初次分配内存块时内存单元分配时的个数 _n_grow_size:增长分配内存块时,内存单元的个数Output: 无Return: 返回一个memory_pool_p的指针Others: 无*************************************************/memory_pool_p memory_pool_init (USHORT _n_unit_size, USHORT _n_init_size, USHORT _n_grow_size ){ memory_pool_p pool; pool = (memory_pool_p)malloc(sizeof(memory_pool_s)); if (NULL == pool) return NULL; pool->p_block = NULL; pool->block_number = 0; pool->n_init_size = _n_init_size; pool->n_grow_size = _n_grow_size; if ( _n_unit_size > 4 ) pool->n_unit_size = (_n_unit_size + (MEMPOOL_ALIGNMENT-1)) & ~(MEMPOOL_ALIGNMENT-1); else if ( _n_unit_size <= 2 ) pool->n_unit_size = 2; else pool->n_unit_size = 4; return pool; }/*************************************************Function: memory_block_init()Description: 内存块初始化函数Input: block:内存块指针 n_number:内存块中内存单元的个数 n_unit_size:内存单元的大小Output: 无Return: 无Others: 无*************************************************/void memory_block_init (memory_block_p block, USHORT n_number, USHORT n_unit_size) { block->n_first = 1; block->p_next = NULL; block->n_size = n_number * n_unit_size; //DEBUGI("%d * %d = %d\n", n_number, n_unit_size, n_number * n_unit_size ); //DEBUGI("block->n_size = %ld\n", block->n_size); block->n_free = n_number - 1; char * p_data = block->a_data; USHORT i; for (i = 1; i < n_number; i++) { *(USHORT *)(p_data) = i; p_data += n_unit_size; }}/*************************************************Function: memory_pool_alloc()Description: 分配一块固定大小的内存,大小等于你在memory_pool_init()中传入的_n_unit_size的大小Input: pool:内存池指针Output: 无Return: 返回一个固定大小内存单元的指针Others: 无*************************************************/ void* memory_pool_alloc (memory_pool_p pool){ if ( !pool->p_block ) { pool->p_block = (memory_block_p)malloc(sizeof(memory_block_s) + (pool->n_unit_size * pool->n_init_size)); if (NULL == pool->p_block) return NULL; pool->block_number++; memory_block_init (pool->p_block, pool->n_init_size, pool->n_unit_size); return (void *)(pool->p_block->a_data); } memory_block_p p_my_block = pool->p_block; while (p_my_block && !p_my_block->n_free ) { p_my_block = p_my_block->p_next; } if ( p_my_block ) { char* pFree = p_my_block->a_data + (p_my_block->n_first * pool->n_unit_size); p_my_block->n_first = *((USHORT*)pFree); p_my_block->n_free--; return (void*)pFree; } else { if ( !pool->n_grow_size ) return NULL; p_my_block = (memory_block_p)malloc(sizeof(memory_block_s) + (pool->n_unit_size * pool->n_grow_size)); if (NULL == p_my_block) return NULL; pool->block_number++; memory_block_init (p_my_block, pool->n_grow_size, pool->n_unit_size); //p_my_block = new(n_grow_size, n_unit_size) FixedMemBlock(n_grow_size, n_unit_size); p_my_block->p_next = pool->p_block; pool->p_block = p_my_block; return (void*)(p_my_block->a_data); } }/*************************************************Function: memory_pool_free()Description: 释放分配的内存 Input: pool:内存池指针 pFree:待释放内存的指针Output: 无Return: 无Others: 无*************************************************/void memory_pool_free ( memory_pool_p pool, void *pFree ){ if (NULL == pFree) return; memory_block_p p_my_block = pool->p_block; while ( ((ULONG)p_my_block->a_data > (ULONG)pFree) || ((ULONG)pFree >= ((ULONG)p_my_block->a_data + p_my_block->n_size)) ) { p_my_block = p_my_block->p_next; if (NULL == p_my_block) { return; } } DEBUGI("-------------------------------------------\n"); DEBUGI("n_first : %d\tn_size : %ld\tn_free : %d\n", \ p_my_block->n_first, p_my_block->n_size, p_my_block->n_free); p_my_block->n_free++; *((USHORT*)pFree) = p_my_block->n_first; p_my_block->n_first = (USHORT)(((ULONG)pFree-(ULONG)(p_my_block->a_data)) / pool->n_unit_size); DEBUGI("n_first : %d\tn_size : %ld\tn_free : %d\n", \ p_my_block->n_first, p_my_block->n_size, p_my_block->n_free); if (p_my_block->n_free * pool->n_unit_size == p_my_block->n_size ) { //if (p_my_block == pool->p_block) /*空闲时全部释放内存块*/ if ((p_my_block == pool->p_block) && (pool->block_number > 1 )) /*至少保留一个内存块*/ { pool->p_block = p_my_block->p_next; DEBUGI("free block\n"); free(p_my_block); pool->block_number--; } } else { DEBUGI("free unit\n"); } }/*************************************************Function: memory_pool_destroy()Description: 销毁内存池 Input: pool:内存池指针Output: 无Return: 无Others: 无*************************************************/ void memory_pool_destroy (memory_pool_p pool){ if (NULL == pool) return; memory_block_p *p_block = &(pool->p_block); memory_block_p tmp; if (NULL == *p_block) { DEBUGI("pool->p_block is NULL\n"); return; } while ( *p_block ) { tmp = *p_block; *p_block = (*p_block)->p_next; DEBUGI("free Block\n"); free(tmp); pool->block_number--; } free(pool);}/*************************************************Function: memory_pool_debug()Description: 打印内存池信息,以及内存块的信息Input: pool:内存池指针Output: 输出内存池信息,以及内存块的信息Return: 无Others: 无*************************************************/void memory_pool_debug (memory_pool_p pool){ DEBUGI("############
############"); DEBUGI("n_init_size : %d\nn_grow_size : %d\nn_unit_size : %d\nblock_number = %d\nmemory_pool_s size = %d", \ pool->n_init_size, pool->n_grow_size, pool->n_unit_size, pool->block_number, sizeof(memory_pool_s)); memory_block_p p_my_block = pool->p_block; while(p_my_block) { DEBUGI("------------
-----------"); DEBUGI("n_first : %d\nn_size : %ld\nn_free : %d\nmemory_block_s size : %d", \ p_my_block->n_first, p_my_block->n_size, p_my_block->n_free, sizeof(memory_block_s)); p_my_block = p_my_block->p_next; }}
/* * mydebug.h * *  Created on: 2013-7-18 *      Author: ckt *      自用公共库 */#ifndef MYDEBUG_H#define MYDEBUG_H#include 
#define OP_FAILED -1#define OP_SUCCESS 0#define TRUE 1#define FALSE 0#define MAX_PATH 260#define SQL_LEN 1024#define ACCOUNT_LEN 64#define INVALID_PACKET -1//for memmem avalable#ifndef _GNU_SOURCE#define _GNU_SOURCE#endif#ifndef NULL#define NULL (void*)0#endiftypedef unsigned int UINT;typedef unsigned long long ULLONG;//typedef unsigned long ULONG;//typedef unsigned short USHORT;typedef unsigned char BYTE;int g_iDebug;static inline void DEBUGI(char *str, ...){#ifdef KK_DEBUG if(g_iDebug > 0) { va_list va; char szBuff[256]; memset(szBuff, 0, sizeof(szBuff)); va_start (va, str); vsnprintf(szBuff, sizeof(szBuff)-1, str, va); va_end(va); printf("%s\n", szBuff); }#endif return ;}static inline void DEBUGE(char *str, ...){ if(g_iDebug > 0) { va_list va; char szBuff[256]; memset(szBuff, 0, sizeof(szBuff)); va_start (va, str); vsnprintf(szBuff, sizeof(szBuff)-1, str, va); va_end(va); printf("****[DEBUG-ERROR] %s\n", szBuff); } return ;}#endif /* MYDEBUG_H */
线程池测试程序,我也用网络数据抓包程序测试了内存池,暂没有发现问题,若有问题,请指出,谢谢
/* * * Copyright (c)  * * All rights reserved. * * * * 文件名称:pooltest.c * * 文件标识:无 * * 摘要:单线程测试程序 * * * * 当前版本:1.0 * * 作者:lishaozhe * * 完成日期:2014年6月12日 * * * * 取代版本: * * 原作者: * * 完成日期: * **/#include 
#include "memory_pool.h"#define NUMBER 5#define UNIT_SIZE 1024 /*定义内存单元大小*/#define UNIT_INIT_NUMBER 5 /*第一次分配内存块时内存单元的个数*/#define UNIT_GROW_NUMBER 5 /*增长分配内存块时内存单元的个数*/extern int g_iDebug;int main(){ g_iDebug = 1; char *buf[NUMBER]; char str[] = "Trying to please other people is largely a futile activity."; memory_pool_p Pool ; /*初始化pool*/ Pool = memory_pool_init(UNIT_SIZE, UNIT_INIT_NUMBER, UNIT_GROW_NUMBER); /*打印pool信息*/ memory_pool_debug(Pool); int i = 0; while (i < NUMBER) { /*分配空间*/ buf[i] = (char *)memory_pool_alloc(Pool); if (NULL == buf[i]) { printf("buf == NULL"); break; } snprintf(buf[i], UNIT_SIZE, "%s %d\n", str, i); i++; } memory_pool_debug(Pool); i = 0; while (i < NUMBER) { printf("buf[%d] = %s\n", i, buf[i]); i++; } i = 0; while (i < NUMBER-1) { /*释放空间*/ memory_pool_free(Pool, buf[i]); i++; } memory_pool_debug(Pool); char *buff = (char *)memory_pool_alloc(Pool); memory_pool_free(Pool, buff); memory_pool_debug(Pool); /*销毁pool*/ memory_pool_destroy(Pool); memory_pool_debug(Pool); return 0;}

Makefile
CFLAGS = -O2 -DHAVE_PF_RING  -Wall -DDEBUG_POOL -D KK_DEBUG /*调试打印宏*/CC =  gcc   pooltest:pooltest.o memory_pool.o	${CC} ${CFLAGS} pooltest.o memory_pool.o  -o $@pooltest.o:memory_pool.hmemory_pool.o:memory_pool.hclean:	rm -rf *.o pooltest
你可能感兴趣的文章
彻底解决mysql中文乱码的办法
查看>>
Excel Sheet Column Number
查看>>
Majority Element
查看>>
Factorial Trailing Zeroes
查看>>
Excel Sheet Column Title
查看>>
Add Two Numbers
查看>>
Balanced Binary Tree
查看>>
Integer to Roman
查看>>
Roman to Integer
查看>>
Minimum Depth of Binary Tree
查看>>
Path Sum
查看>>
Binary Tree Level Order Traversal II
查看>>
Binary Tree Level Order Traversal
查看>>
Symmetric Tree
查看>>
Two Sum
查看>>
Longest Substring Without Repeating Characters
查看>>
Container With Most Water
查看>>
Letter Combinations of a Phone Number
查看>>
3Sum
查看>>
Trapping Rain Water
查看>>