设为首页 加入收藏

TOP

C语言内存池使用模型(六)
2012-11-03 13:20:27 】 浏览:3757
Tags:语言 内存 使用 模型

   
    第一步是先调用_pool_new创建一个空的内存池结构,这个前面已经说明了,操作很简单。看第二步是怎么完成的
   
    static struct pheap *_pool_heap(pool_t p, int size)
   
    {
   
    struct pheap *ret;
   
    struct pfree *clean;
   
    while((ret = _pool__malloc(sizeof(struct pheap))) == NULL) sleep(1);
   
    while((ret->block = _pool__malloc(size)) == NULL) sleep(1);
   
    ret->size = size;
   
    p->size += size;
   
    ret->used = 0;
   
    clean = _pool_free(p, _pool_heap_free, (void *)ret);
   
    clean->heap = ret; /* for future use in finding used mem for pstrdup */
   
    _pool_cleanup_append(p, clean);
   
    return ret;
   
    }
   
    第二步包含下面一些操作:
   
    1、申请一个大小为size的内存块,也就是前方中介绍的pheap结构。
   
    2、把这个内存块的大小size,加到内存池上,就是那个p->size += size;
   
    3、将内存块关联到struct pfree结构。这会指示内存释放的方式,也把内存加入到链表元素上。
   
    4、将struct pfree结构关联到内存池,其实就是加到链表的末尾。
   
    下面会讨论第3和第4部是怎么实现的。
   
    五、内存池管理内存机制(单链表管理结构)
   
    这里主要是讨论,从内存块申请开始,就是申请了一个pheap结构指向内存块,然后内存池以什么形式将内存块组织起来,这一个很重要的结构是struct pfree结构。
   
    看一下前面申请内存块之后,这时还只是一个pheap结构,没有和内存池关联起来,在前方我们看到,是通过下面代码进行关联的
   
    clean = _pool_free(p, _pool_heap_free, (void *)ret);
   
    clean->heap = ret; /* for future use in finding used mem for pstrdup */
   
    _pool_cleanup_append(p, clean);
   
    _pool_free为该内存块定义的一个结构进行初始化,如下调用
   
    static struct pfree *_pool_free(pool_t p, pool_cleanup_t f, void *arg)
   
    {
   
    struct pfree *ret;
   
    while((ret = malloc(sizeof(struct pfree))) == NULL) sleep(1);
   
    ret->f = f;
   
    ret->arg = arg;
   
    ret->next = NULL;
   
    return ret;
   
    }
   
    这个函数只是定义了一个sturct pfree结构,基本上是用struct pheap这个结构对其进行初始化的,可以看出这个结构的arg和heap域都是指向struct pheap结构。这是很重要的一步,内存池主要是管理这个结构的。
   
    注意这里的pool_cleanup_t是一个函数指针,在我们这里,它是_pool_heap_free.用于指示如何释放这个内存块,实现很简单,如下:
   
    static void _pool_heap_free(void *arg)
   
    {
   
    struct pheap *h = (struct pheap *)arg;
   
    free(h->block);
   
    free(h);
   
    }
   
    这个释放函数就很简单了吧,下面继续我们话题。
   
    前文说了内存池包含链表,管理内存块,那接下来的操作是不是要将这个内存块【struct pfree】加到链表上。看一下_pool_cleanup_append函数做哪些工作:
   
    static void _pool_cleanup_append(pool_t p, struct pfree *pf)
   
    {
   
    struct pfree *cur;
   
    if(p->cleanup == NULL)
   
    {
   
    p->cleanup = pf;
   
    p->cleanup_tail = pf;
   
    return;
   
    }
   
    cur = p->cleanup_tail;
   
    cur->next = pf;
   
    p->cleanup_tail = pf;
   
    }
   
    这个函数很简单,将struct pfree结构加到内存池的cleanup_tail链表的末尾,并将新的cleanup_tail指向刚加入的pfree结构。
   
    到这里,就完成了内存从调用malloc分配至加入到内存池的过程,再回顾一下:
   
    1、调用malloc分配内存块,并赋值给struct pheap结构。
   
    2、将struct pheap结构封装成struct pfree结构,这样struct pheap结构就可以成为链表上的元素。
   
    3、将struct pfree结构加入到struct pool_sturct结构【这是内存池的结构】的链表末尾。
   
    六、内存池的释放
   
    在内存池的使命结束后,我们需要释放内存池,不仅仅是struct pool_struct这个结构,还包括链表上的内存块。
   
    void pool_free(pool_t p)
   
    {
   
    struct pfree *cur, *stub;
   
    if(p == NULL) return;
   
    cur = p->cleanup;
   
    while(cur != NULL)
   
    {
   
    (*cur->f)(cur->arg); // 这会释放用malloc分配的内存块和struct pheap结构所占用的内存。这就是前文的_pool_heap_free函数
   
    stub = cur->next;
   
    free(cur);  // 释放pfree结构。
   
    cur = stub;
   
    }
   
    free(p); //释放pool_struct结构所占用的内存。
   
    }

        

首页 上一页 3 4 5 6 7 下一页 尾页 6/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C小程序 - 信号量 下一篇C语言的技巧知识

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目