[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


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