RT-Thread学习记录15 内存池的使用

以下为看视频笔记..........

1. 内存池的介绍

 

动态内存堆可以分配任意大小的内存块,非常灵活和方便。但其存在明显的缺点:一是分配效率不高,在每次分配时,都要进行空闲内存块查找;二是容易产生内存碎片。

为了提高内存分配的效率,并且避免内存碎片,RT-Thread 提供了另外一种内存管理方法:内存池(Memory Pool )

内存池是一种内存分配方式,用于分配大量大小相同的小内存块。使用内存池可以极大地加快内存分配与释放的速度,且能尽量避免内存碎片化。

RT-Thread的内存池支持线程挂起功能,当内存池中无空闲内存块时,申请线程会被挂起,直到内存池中有新的可用内存块,再将挂起的线程唤醒。基于这个特点内存池非常适合需要通过内存资源进行同步的场景。

2. 内存池工作机制

 

内存池在创建时先从系统中获取一大块内存 ( 静态或动态),然后分成相同大小的多个小内存块,这些小内存块通过链表连接起来(此链表也称为空闲链表)。线程每次申请分配内存块的时候,系统从空闲链表中取出链头上第一个内存块, 提供给申请者。

3. 内存池控制块

在RT_Thread中,内存池控制块是操作系统用于管理内存池的一个数据结构。

struct  rt_mempool
{
    struct rt_object  parent:
    void         *start_address;//保存申请的内存的地址
    rt_size_t         size;     //记录大内存块的大小
    rt_size_t         block_size; //记录大内存块中小内存块的大小
    rt_uint8_t        *block_list; //小内存块的列表
    rt_size_t      block_total_count;//总共有多少小内存块
    rt_size_t      block_free_count;  //当前小内存块空闲的个数
    rt_list_t      suspend_thread;  //内存块支持挂起,记录线程挂起在内存池上的列表
    rt_size_t      suspend_thread_count;//记录线程挂起在内存池上的数目
}
typedef  struct  rt_mempool  *rt_mp_t  //内存块的指针型定义

定义静态内存池:struct  rt_mempool  static_mp

定义动态内存池:rt_mp_t  dynamic_mp

4.  内存池的操作

静态内存池的初始化与脱离

rt_err_t  rt_mp_init(struct rt_mempool  *mp,const  char  *name,
                    void  *start,rt_size_t  size,rt_size_t  block_size)
//第一个参数为内存控制块的地址,第二个参数为内存控制块起一个名字,注意RT-Thread的所有对象都要起一个名称。第三个参数为系统的内存地址输入给参数,可以先用数组的方式定义出来。第四个参数为内存池的大小。第五个参数为内存池中内存块的大小(数值为4的整数倍)。计算内存池中有多少内存块:
//size/(block_size+4).内存块都是用链表连接的,4是一个指针的长度
rt_err_t  rt_mp_detach(struct  rt_mempool  *mp)
//第二个参数为内存块数目。第三个参数为内存块的大小

动态内存池的创建与删除

rt_mp_t  rt_mp_create(const char *name,rt_size_t  block_count,rt_size_t  block_size)

rt_err_t  rt_mp_delete(rt_mp_t  mp)

申请内存块

void  rt_mp_alloc(rt_mp_t mp ,rt_int32_t time)
//第一个参数为内存块控制块的地址,指示从哪个内存池分配内存控制块,第二个参数为当内存池满时线程挂起时间,当time>0,挂起time 时间,当time = 0,立即返回,time < 0 ,线程阻塞在内存池的申请上。

释放内存块

void rt_mp_free(void *block)//输入内存块的地址,释放那个内存块

5. 例程在memp_sample.c

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章