11.内存池//依据RT-Thread内核编程的学习记录(非内核实现)

内存池,申请出得内存情况是内存块,相对于动态内存申请rt_malloc()申请的内存,rt_mp_alloc()申请的内存块的开头和结尾会包含指向上一块的指针和指向下一块内存块的指针。每块内存块的大小相等。动态申请内存不会出现任务调度,内存池申请内存会出现任务调度。

1.初始化内存池对象

/*静态初始化内存池对象*/
static rt_uint8_t *ptr[50];
static rt_uint8_t static_mempool[1024];
static struct rt_mempool static_mp;

rt_mp_init(&static_mp, "name", &static_mempool[0], sizeof(static_mempool), size of each memory blocks);

/*动态初始化内存池对象*/
static rt_uint8_t *ptr[50];
static rt_mp_t dynamic_mp = RT_NULL;

dynamic_mp = rt_mp_creat("name",the count of memory blocks,the size of each memory blocks);


2.内存池的申请和释放

/*内存池的申请*/
static uint8_t ptr[xx];

ptr[i] = rt_mp_alloc(&static_mp, time);

ptr[i] = rt_mp_alloc(dynamic_mp, time);

/*内存池的释放*/

rt_mp_free(&ptr[i]);

3.删除内存池对象

/*删除内存池对象*/


rt_mp_detach(&static_mp);

rt_mp_delete(dynamic_mp);

4.例程

/*
 * 程序清单:内存池例程
 *
 * 这个程序会创建一个静态的内存池对象,2个动态线程。
 * 一个线程会试图从内存池中获得内存块,另一个线程释放内存块
 * 内存块
 */
#include <rtthread.h>

static rt_uint8_t *ptr[50];
static rt_uint8_t mempool[1024];
static struct rt_mempool mp;

#define THREAD_PRIORITY      25
#define THREAD_STACK_SIZE    512
#define THREAD_TIMESLICE     5

/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;

/* 线程1入口 */
static void thread1_mp_alloc(void *parameter)
{
    int i;
    for (i = 0 ; i < 15 ; i++)
    {
        if (ptr[i] == RT_NULL)
        {
            /* 试图申请内存块50次,当申请不到内存块时,
               线程1挂起,转至线程2运行 */
            ptr[i] = rt_mp_alloc(&mp, RT_WAITING_FOREVER);
            if (ptr[i] != RT_NULL)
                rt_kprintf("allocate No.%d\n", i);
        }
    }
}

/* 线程2入口,线程2的优先级比线程1低,应该线程1先获得执行。*/
static void thread2_mp_release(void *parameter)
{
    int i;

    rt_kprintf("thread2 try to release block\n");
    for (i = 0; i < 15 ; i++)
    {
        /* 释放所有分配成功的内存块 */
        if (ptr[i] != RT_NULL)
        {
            rt_kprintf("release block %d\n", i);
            rt_mp_free(ptr[i]);
            ptr[i] = RT_NULL;
        }
    }
}

int mempool_sample(void)
{
    int i;
    for (i = 0; i < 50; i ++) ptr[i] = RT_NULL;        //惧怕野指针

    /* 初始化内存池对象 */
    rt_mp_init(&mp, "mp1", &mempool[0], sizeof(mempool), 80);

    /* 创建线程1:申请内存池 */
    tid1 = rt_thread_create("thread1", thread1_mp_alloc, RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY, THREAD_TIMESLICE);
    if (tid1 != RT_NULL)
        rt_thread_startup(tid1);


    /* 创建线程2:释放内存池*/
    tid2 = rt_thread_create("thread2", thread2_mp_release, RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY + 1, THREAD_TIMESLICE);
    if (tid2 != RT_NULL)
        rt_thread_startup(tid2);

    return 0;
}


/*程序打印结果*/
/*
allocate No.0

allocate No.1

allocate No.2

allocate No.3

allocate No.4

allocate No.5

allocate No.6

allocate No.7

allocate No.8

allocate No.9

allocate No.10

allocate No.11

thread2 try to release block

release block 0

allocate No.12

release block 1

allocate No.13

release block 2

allocate No.14

release block 3

release block 4

release block 5

release block 6

release block 7

release block 8

release block 9

release block 10

release block 11

release block 12

release block 13

release block 14

*/

打印中,内存块未申请到第13块内存导致调度等待,由此线程2开启,开始删除内存块。为什么是第13块申请不到,是因为内存池的首位均包含一个指针,所以表面从内存池的初始化是80个一个空间,实际上是84。1024 / 84 = 12 ,所以想要获取到内存块必须要等待调度。

猜你喜欢

转载自blog.csdn.net/xiangxistu/article/details/82831133
今日推荐