c 单线程内存池实现

本文实现了单线程内存池,其原理是根据里《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;

}


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.h
memory_pool.o:memory_pool.h
clean:
	rm -rf *.o pooltest


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值