本文实现了单线程内存池,其原理是根据里《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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#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("############<pool info>############");
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("------------<block info>-----------");
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 <stdarg.h>
#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
#endif
typedef 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 <stdio.h>
#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;
}
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.h
memory_pool.o:memory_pool.h
clean:
rm -rf *.o pooltest