1. 程式人生 > >[RTT例程練習] 3.3 靜態記憶體管理,記憶體池mempool

[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


相關推薦

[RTT練習] 3.3 靜態記憶體管理記憶體mempool

記憶體池是一種靜態的記憶體管理方法。它預先將一塊固定連續的記憶體區域劃分成幾個大小不同的塊。使用者申請時就將對應大小的記憶體塊給他。這種方法的優點是不會有記憶體碎片,但不夠靈活,適用於需要頻繁存取的場合,例如buffer。 這個例子有兩個執行緒。thread1不停分配記憶體

[RTT練習] 1.1 動態執行緒建立刪除

建立兩個動態執行緒,thread2 執行4s後刪除thread1。 這裡兩個都為動態執行緒,所謂動態執行緒即在堆中動態建立,刪除之後也從RAM中消失。區別於靜態執行緒。 由於是動態,所以需開啟 #define RT_USING_HEAP 以下是application.c

C++面試常見題目4_記憶體管理記憶體洩露

記憶體管理 定義:記憶體管理是指軟體執行時對計算機記憶體資源的分配和使用的技術。其最主要的目的是如何高效,快速的分配,並且在適當的時候釋放和回收記憶體資源。 在C++中記憶體分為5個區,分別是堆、棧、自由儲存區、全域性/靜態儲存區和常量儲存區。 堆:堆是

C++ Primer Plus第六版編練習---第3章 處理數據(未完待續)

foo ons enter ++ har HA CI return include 1. #include <iostream> const int CONVER_FACTOR = 12; int main(int argc, char* argv[]){ in

神經網路-使用(3-1)結構的神經網路實現與、或、異或三種邏輯運算

以下程式碼來自Deep Learning for Computer Vision with Python第十章。 本例程需要在同一檔案內新建四個檔案。分別是1、perceptron.py;2、perceptron_or.py;3、perceptron_and.py;4、pe

java練習(多執行緒[執行緒的優先順序等等])

//設定執行緒的優先順序 public class TestThread1 { public static void main(String[] args) { Thread t1 = new Thread(new T1()); Thread t2 = new T

【C 語言】記憶體管理 ( 動態記憶體分配 | 棧 | 堆 | 靜態儲存區 | 記憶體佈局 | 野指標 )

一. 動態記憶體分配 1. 動態記憶體分配相關概念 動態記憶體分配 : 1.C語言操作與記憶體關係密切 : C 語言中的所有操作都與記憶體相關 ; 2.記憶體別名 : 變數 ( 指標變數 | 普通變數 ) 和 陣

【原始碼】記憶體管理--得記憶體者得天下

程序和記憶體管理堪稱核心的任督二脈,是最重要的兩部分,這兩部弄清楚了,主體架構也就確立,其它都是支脈。而這兩者中,又數記憶體管理最難,所以,得記憶體者得天下。   (一) 1.buddy(夥伴)機制。 以頁為單位的大記憶體。   2.slab機制。 管

記憶體管理記憶體分配介面總結

一、簡介:     記憶體分配的介面有很多,不同的申請函式有不同的功能,下面會做詳細的介紹和對比。 kmalloc:基於slab分配器,用於分配小記憶體,物理空間連續的記憶體塊; vmalloc:用於分配大記憶體,虛擬地址連續的記憶體; malloc:為使用者空間分配程序地

記憶體管理記憶體洩漏檢測kmemleak

一、簡介:     Kmemleak工作於核心態,Kmemleak 提供了一種可選的核心洩漏檢測,其方法類似於跟蹤記憶體收集器。當獨立的物件沒有被釋放時,其報告記錄在 /sys/kernel/debug/kmemleak中,Kmemcheck能夠幫助定位大

Linux記憶體管理 (26)記憶體相關工具

  1. vmstat 參照《Linux CPU佔用率監控工具小結-vmstat》 2. memstat memstat可以通過sudo apt install memstat安裝,安裝包括兩個檔案memstat和memstat.conf。 其中memstat.conf是memstat配置

【軟體開發底層知識修煉】三 深入淺出處理器之三 記憶體管理記憶體管理單元(MMU)

上一篇文章學習了中斷的概念與意義,以及中斷的應用-斷點除錯原理。點選連結複習上一篇文章:中斷的概念與意義 本片文章繼續學習處理器相關的知識-記憶體管理。包括:記憶體管理單元MMU的作用,虛擬記憶體與實體記憶體之間的對映方式,頁表的概念,快取記憶體(Cache)的作用,實體記憶體與快取

啟動期間的記憶體管理之bootmem_init初始化記憶體管理–Linux記憶體管理(十二)

1. 啟動過程中的記憶體初始化 首先我們來看看start_kernel是如何初始化系統的, start_kerne定義在init/main.c?v=4.7, line 479 其程式碼很複雜, 我們只截取出其中與記憶體管理初始化相關的部分, 如下所示 table th:nth-of-type(1){

記憶體溢位記憶體洩漏記憶體抖動

記憶體溢位,記憶體洩漏,記憶體抖動你都碰到過嗎?怎麼解決的?如何區分這幾種情況?怎麼解決由記憶體洩漏而導致的記憶體溢位? 記憶體優化 . 記憶體洩露 記憶體溢位 記憶體抖動 分析與解決 記憶體溢位和記憶體洩漏的區別、產生原因以及解決方案 一、記憶體溢位: (一)、定義: 記憶體溢

Java記憶體管理記憶體洩露是什麼?什麼情況下會導致記憶體洩露?

文章目錄 1. 靜態類的使用 2. 資源連線的使用 3. 監聽器的使用 雖然Java擁有垃圾回收機制,但同樣會出現記憶體洩露問題,我們說一下比較主要的三種情況。 1. 靜態類的使用 諸如 HashMap、Vector 等集

深入淺出記憶體管理--實體記憶體框架

NUMA 首先需要介紹一個NUMA的概念,非一致性記憶體訪問模型,在這種系統中,CPU訪問不同記憶體單元的時間可能是不一樣的,實體記憶體被劃分為不同的Node節點來進行管理,對於單CPU的系統也可能使用NUMA,因為這些系統的實體記憶體有可能不一定是整塊的,而是中間包含有很大的洞,因

深入淺出記憶體管理--高階記憶體對映之pkmap(永久對映)

我們知道系統中的高階記憶體是不能作為直接對映區對映到核心空間的,那麼我們想要使用它怎麼辦呢?前面的文章我們已經有過相關的介紹,可以使用三種方法,分別是pkmap(永久對映)/fixmap(臨時固定對映)/vmlloc,本文主要介紹pkmap,也就是永久對映。 入口函式 首先我們來

深入淺出記憶體管理--快取記憶體(cache memory)和轉換後援緩衝(TLB)

快取記憶體(Cache memory) CPU的執行速度時非常快的,當今的CPU主頻都是GHZ級別的,而對於記憶體DDR來說,每次存取操作都會耗用很多的時鐘週期,這意味著,CPU需要等待很長時間來完成一次讀或者寫操作。 為了縮小CPU和DDR兩者之間速度上的不匹配造成的等待問題,硬體

磁碟排程演算法記憶體排程記憶體分配策略

磁碟是可供多個程序共享的裝置,當有多個程序都要求訪問磁碟時,應採用一種最佳排程演算法,以使各程序對磁碟的平均訪問時間最小。由於在訪問磁碟的時間中,主要是尋道時間。因此: 磁碟排程演算法的目標是使磁碟的平均尋道時間最少 1,先來先服務(FIFS,first c

安卓APP實戰(二):Activity管理記憶體回收及LeakCanary監測

每一個Activity元件都是一個單獨的介面,承載著與使用者互動的任務。也是應用最基本的功能之一,在不同介面之間切換,並實現不同的功能。 每一個程式必須要有一個Activity作為入口(Manifest檔案中將其<category>標籤設定為LAUNCHER),然後通過介面控制到