zoukankan      html  css  js  c++  java
  • [RTT例程练习] 3.3 静态内存管理,内存池mempool

    内存池是一种静态的内存管理方法。它预先将一块固定连续的内存区域划分成几个大小不同的块。使用者申请时就将对应大小的内存块给他。这种方法的优点是不会有内存碎片,但不够灵活,适用于需要频繁存取的场合,例如buffer。

    这个例子有两个线程。thread1不停分配内存块,但其中并没有使用delay() 来使自己挂起,所以thread2 由于优先级低于 thread1 而一直得不到运行。thread1 分配完所有内存块以后,又试着再取得一个内存块,由于内存块已经被分配完,所以thread1 会因为得不到资源而被挂起。此时thread2 开始运行,释放内存块,释放了一个以后,thread1 的等待条件满足而执行了一次,然后thread2 继续运行直至结束。

    程序:

    #include <rtthread.h>
    
    static rt_uint8_t *ptr[48];
    static rt_uint8_t mempool[4096];
    static struct rt_mempool mp;
    
    static rt_thread_t tid1 = RT_NULL;
    static rt_thread_t tid2 = RT_NULL;
    
    static void thread1_entry(void* parameter)
    {
        int i,j = 1;
        char *block;
    
        while(j--)
        {
            for (i = 0; i < 48; i++)
            {
                /* 申请内存块 */
                rt_kprintf("allocate No.%d\n", i);
                if (ptr[i] == RT_NULL)
                {
                    ptr[i] = rt_mp_alloc(&mp, RT_WAITING_FOREVER);
                }
            }
    
            /* 继续申请一个内存块,因为已经没有内存块,线程应该被挂起 */
            block = rt_mp_alloc(&mp, RT_WAITING_FOREVER);
            rt_kprintf("allocate the block mem\n");
            /* 释放这个内存块 */
            rt_mp_free(block);
            block = RT_NULL;
        }
    }
    
    static void thread2_entry(void *parameter)
    {
        int i,j = 1;
    
        while(j--)
        {
            rt_kprintf("try to release block\n");
    
            for (i = 0 ; i < 48; i ++)
            {
                /* 释放所有分配成功的内存块 */
                if (ptr[i] != RT_NULL)
                {
                    rt_kprintf("release block %d\n", i);
    
                    rt_mp_free(ptr[i]);
                    ptr[i] = RT_NULL;
                }
            }
    
            /* 休眠10个OS Tick */
            rt_thread_delay(10);
        }
    }
    
    
    
    int rt_application_init()
    {
        int i;
        for (i = 0; i < 48; i ++) ptr[i] = RT_NULL;
    
        /* 初始化内存池对象 ,每块分配的大小为80,但是另外还有大小为4的控制头,所以实际大小为84*/
        rt_mp_init(&mp, "mp1", &mempool[0], sizeof(mempool), 80);
    
        /* 创建线程1 */
        tid1 = rt_thread_create("t1",
            thread1_entry, RT_NULL, 512, 8, 10);
        if (tid1 != RT_NULL)
            rt_thread_startup(tid1);
    
        /* 创建线程2 */
        tid2 = rt_thread_create("t2",
        thread2_entry, RT_NULL, 512, 9, 10);
        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
    allocate No.12
    allocate No.13
    allocate No.14
    allocate No.15
    allocate No.16
    allocate No.17
    allocate No.18
    allocate No.19
    allocate No.20
    allocate No.21
    allocate No.22
    allocate No.23
    allocate No.24
    allocate No.25
    allocate No.26
    allocate No.27
    allocate No.28
    allocate No.29
    allocate No.30
    allocate No.31
    allocate No.32
    allocate No.33
    allocate No.34
    allocate No.35
    allocate No.36
    allocate No.37
    allocate No.38
    allocate No.39
    allocate No.40
    allocate No.41
    allocate No.42
    allocate No.43
    allocate No.44
    allocate No.45
    allocate No.46
    allocate No.47
    try to release block
    release block 0
    allocate the block mem
    release block 1
    release block 2
    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
    release block 15
    release block 16
    release block 17
    release block 18
    release block 19
    release block 20
    release block 21
    release block 22
    release block 23
    release block 24
    release block 25
    release block 26
    release block 27
    release block 28
    release block 29
    release block 30
    release block 31
    release block 32
    release block 33
    release block 34
    release block 35
    release block 36
    release block 37
    release block 38
    release block 39
    release block 40
    release block 41
    release block 42
    release block 43
    release block 44
    release block 45
    release block 46
    release block 47


  • 相关阅读:
    Golang语言编程规范
    关于redis的几件小事(三)redis的数据类型与使用场景
    关于redis的几件小事(二)redis线程模型
    关于redis的几件小事(一)redis的使用目的与问题
    关于MQ的几件小事(七)如果让你设计一个MQ,你怎么设计
    关于MQ的几件小事(六)消息积压在消息队列里怎么办
    关于MQ的几件小事(五)如何保证消息按顺序执行
    关于MQ的几件小事(四)如何保证消息不丢失
    关于MQ的几件小事(三)如何保证消息不重复消费
    关于MQ的几件小事(二)如何保证消息队列的高可用
  • 原文地址:https://www.cnblogs.com/lyyyuna/p/4123917.html
Copyright © 2011-2022 走看看