线程安全的内存池 c++ 尝试(二)
来源:互联网 发布:山东网络春晚2016直播 编辑:程序博客网 时间:2024/06/06 02:23
mem_pool.h
#include "mempool.h"
#include <stdio.h>
//links 数组存储了内存池中所有的 存储内存块的链表;
// 因为该内存池约定内存块的大小共有17 种,分别为:
//16b,32b,64b,128b,256b,512b,1k,2k,4k,8k,16k,32k,64k,
//128k,256k,512k,1m,所以links 数组大小为17,
// 如果申请的内存块的大小超过1m,内存池不另存储,直接申请,
//直接释放;
mlink links[17];
static FILE * loginfo;
//初始化内存池;
void mempool_init()
{
for(int i=0;i<17;i++)
{
//下面的操作是给每一个链表申请一个空闲的内存块,
//该内存块是无法分配出去的,即每一个链表至少有一个
//空闲的内存块,该内存块只是为了处理链表的添加和
//删除时操作的方便,虽然浪费了内存,却换来了效率;
links[i].count=1;
links[i].phead=malloc(((unsigned int)1)<<(i+4));
links[i].ptail=links[i].phead;
mem_block_info * p=(mem_block_info*)links[i].phead;
p->size=((unsigned int)1)<<(i+4);
p->pnext=0;
MUTEXINIT(&(links[i].head_mutex));
MUTEXINIT(&(links[i].tail_mutex));
}
loginfo=fopen("mempool.txt","w+");
}
//从内存池中申请 大小为 size B 的空间;
void * mempool_malloc(unsigned int size)
{
//实际向内存池匹配的内存块大小为size+sizeof(mem_block_info);
unsigned int memblock_size=size+MEMBLOCKINFOSIZE;
//因为内存块前 MEMBLOCKINFOSIZE 个字节是内存池记录
//该内存块信息所用的,所以当返回该内存块的指针时,
//需向后移动MEMBLOCKINFOSIZE 个字节;
printf("mempool_malloc: memblock_size 1: %d b\n",memblock_size);
fprintf(loginfo,"mempool_malloc: memblock_size 1: %d b\n",memblock_size);
//如果memblock_size>1m,直接向系统申请;
if(memblock_size>1024*1024)
{
void * p= malloc(memblock_size);
((mem_block_info *)p)->size=memblock_size;
((mem_block_info*)p)->pnext=0;
return (void *)p+MEMBLOCKINFOSIZE;
}
//计算与memblock_size 匹配的链表的下标;
unsigned int count=4;
while(memblock_size>(((unsigned int)1)<<count))
count++;
memblock_size=(((unsigned int)1)<<count);
printf("mempool_malloc: memblock_size 2: %f k\n",(memblock_size)/((double)1024.0));
fprintf(loginfo,"mempool_malloc: memblock_size 2: %f k\n",(memblock_size)/((double)1024.0));
int index=count-4;
int flag;
void * ret;
//检查该链表是否有空闲的内存块;
MUTEXLOCK(&(links[index].head_mutex));
//该链表没有空闲的内存块
if(links[index].phead==links[index].ptail)
{
flag=EMPTY;
void * p=malloc(memblock_size);
if(p==0)
ret=0;
else
{
((mem_block_info *)p)->size=memblock_size;
((mem_block_info *)p)->pnext=0;
ret=(void *)p+MEMBLOCKINFOSIZE;
links[index].count++;
}
MUTEXUNLOCK(&(links[index].head_mutex));
}
else//该链表有空闲的内存块;
{
flag=NOTEMPTY;
void * p=links[index].phead;
links[index].phead=((mem_block_info *)p)->pnext;
ret=p+MEMBLOCKINFOSIZE;
MUTEXUNLOCK(&(links[index].head_mutex));
}
/*if(flag==EMPTY)
{
void * p=malloc(memblock_size);
((mem_block_info *)p)->size=memblock_size;
((mem_block_info *)p)->pnext=0;
ret=p+MEMBLOCKINFOSIZE;
}*/
return ret;
}
//向内存池释放内存空间;
void mempool_free(void * pointer)
{
//向前移动指针,获取该内存块的信息
pointer-=MEMBLOCKINFOSIZE;
unsigned int size=((mem_block_info *)pointer)->size;
printf("mempool_free size: %f k\n",(size)/((double)1024.0));
fprintf(loginfo,"mempool_free size: %f k\n",(size)/((double)1024.0));
//该内存块的大小大于1m ,直接释放给系统;
if(size>1024*1024)
{
free(pointer);
return;
}
//计算与该内存块匹配的链表的下标;
int count=4;
while(size>((unsigned int)1)<<count)
count++;
if(size<((unsigned int)1)<<count)
{
printf("mempool_free error : size is not right \n");
fprintf(loginfo,"mempool_free error : size is not right \n");
exit(0);
}
int index=count-4;
//将该内存块添加到与之匹配的链表中去;
MUTEXLOCK(&(links[index].tail_mutex));
((mem_block_info *)pointer)->pnext=0;
((mem_block_info *)links[index].ptail)->pnext=pointer;
links[index].ptail=pointer;
MUTEXUNLOCK(&(links[index].tail_mutex));
return;
}
//获得内存池的内存块的全部内存空间;
unsigned int getTotalMemory()
{
unsigned int ret=0;
for(int i=0;i<17;i++)
{
ret+=(((unsigned int)1)<<(i+4))*links[i].count;
printf("the links[i] i: %d, count: %d \n",i,links[i].count);
fprintf(loginfo,"the links[i] i: %d, count: %d \n",i,links[i].count);
}
printf("******get the total memory**** : %d \n",ret);
fprintf(loginfo,"******get the total memory**** : %f m\n",ret/(1024*((double)1024)));
return ret;
}
//销毁内存池;
void mempool_destroy()
{
for(int i=0;i<17;i++)
{
void * pointer=links[i].phead;
void * tmp;
while(pointer!=0)
{
tmp=pointer;
pointer=((mem_block_info *)tmp)->pnext;
free(tmp);
links[i].count--;
}
if(links[i].count>0)
{
printf("error! threre is wrong with the memory :%d\n",i);
fprintf(loginfo,"error! threre is wrong with the memory :%d\n",i);
}
MUTEXDESTROY(&(links[i].head_mutex));
MUTEXDESTROY(&(links[i].tail_mutex));
}
return;
}
//*************************************************************
下面是一个测试代码:
#include "pthread.h"
#include "mempool.h"
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
THREADFUNCDECL(new_memory,args)
{
srand(12);
unsigned int size=rand()%(1000000)+1;
size=sizeof(double)*20;
printf("the main test size: %d b\n",size);
printf("the main test size: %f k\n",size/(double(1024.0)));
printf("new memory\n");
void * pointer=mempool_malloc(size);
for(int i=0;i<20;i++)
((double *)pointer)[i]=0.0;
for(int i=0;i<20;i++)
printf("data: %f ",*((double *)pointer));
Sleep(50);
printf("free memory\n");
mempool_free(pointer);
}
int main()
{
srand(time(0));
mempool_init();
THREAD thread;
THREADID id;
for(int i=0;i<100;i++)
{
THREADCREATE(new_memory,NULL,thread,id);
printf("the total memory size is : %f m\n",getTotalMemory()/(double(1024*1024)));
Sleep(0);
}
Sleep(10000);
mempool_destroy();
return 0;
}
/**********************************************************************
因为内存块的申请和释放的复杂度都是O(1),并且在多线程的环境下,这两个操作可以互不干扰,提高了程序的并发性,效率应该不是太差,
虽然这只是一个雏形,不过也是一个不错的尝试了。
- 线程安全的内存池 c++ 尝试(二)
- 线程安全的内存池 c++ 实现尝试(一)
- 线程安全内存池
- 线程安全(二)
- Android ContentProvider的线程安全(二)
- c# SingleTon的线程安全(存档)
- 实现一个线程安全的内存池(使用线程私有数据机制TSD来实现)
- java线程安全(二)
- 线程安全总结(二)
- 线程安全总结(二)
- 线程安全总结(二)
- 线程安全总结(二)
- 线程安全总结(二)
- 线程安全总结(二)
- 安全线程队列(二)
- 【RLIB】线程安全内存池(Memory) 的简易C++实现
- 简单的内存池实现(非线程安全)
- linux下的一个简单线程安全内存池实现
- [jQery]为文本框指定下拉弹出层
- 我知道 这是个新的开始。
- 传华为接洽投行欲赴美上市
- Linux驱动程序学习笔记(1)
- 工程师解读:为何华为手机干不过小米
- 线程安全的内存池 c++ 尝试(二)
- 详析:谷歌为何紧急封杀阿里云 OS?
- C语言运算符优先级
- Ldd3编译遇到常见问题汇总
- 央视《每周质量报告》:揭秘假宽带真相
- Firefox 18 将支持 OS X 的视网膜屏
- 春晚就看赵本山 手机只买iPhone5
- BNU - Dividing Stones 记忆化搜索
- c++学习资源