APR學習-消息池的設計與使用

一、任務消息的抽象池,用於從中分配任務消息
/** Abstract pool of task messages to allocate task messages from */
struct apt_task_msg_pool_t {
    void (*destroy)(apt_task_msg_pool_t *pool);
 
    apt_task_msg_t* (*acquire_msg)(apt_task_msg_pool_t *pool);
    void (*release_msg)(apt_task_msg_t *task_msg);
 
    void       *obj;
    apr_pool_t *pool;
};
 
 
二、動態分配消息的結構體,並沒有實際池的存在
struct apt_msg_pool_dynamic_t {
    apr_size_t size;
};
 
 
消息池的創建函數,看一下函數聲明:
APT_DECLARE(apt_task_msg_pool_t*) apt_task_msg_pool_create_dynamic(apr_size_t msg_size, apr_pool_t *pool)
 
msg_size是用戶私有的、自定義的消息內容,pool是內存池。
這個函數主要作用是創建一個任務消息的抽象池,定義了消息獲取、消息釋放的函數指針並且賦值實現。另外還使用了一個銷燬消息池的函數指針。
動態分配消息的結構體(apt_msg_pool_dynamic_t)的實例變量,賦值給了obj這個指針。因爲這個結構體中唯一的一個成員變量size,它是自定義消息大小 + apt_task_msg_t結構大小,與外部上下文內容強相關的,這賦值給obj也很好理解。
 
消息池裏面,有三個東西: 內存池、外部對象(apt_msg_pool_dynamic_t)、消息池操作方法(acquire_msg、release_msg、destroy)。
 
來看一下task_msg_t結構:
/** Task message is used for inter task communication */
struct apt_task_msg_t {
    /** Message pool the task message is allocated from */
    apt_task_msg_pool_t *msg_pool;
    /** Task msg type */
    int                  type;
    /** Task msg sub type */
    int                  sub_type;
    /** Context specific data */
    char                 data[1];
};
 
要留意的是結構體最後一個成員變量是 char data[1],這兒使用長度爲1的數組的主要原因是方便管理內存,如果直接使用指針而不是使用數組,那麼在malloc分配內存時,就必須先分配結構體一次,然後在分配結構體中的指針一次。此時分配的內存已經跟分配結構體的內存不連續了,所以要分別管理。而如果使用數組,那麼只需要一次就可以全部分配出來,用完之後,一次釋放。這樣分配了一段連續的內存,減少內存的碎片化。至於這兒使用了char data[1] 而沒有使用char data[0]的原因,是出於可移植性的考慮。有些編譯器不支持[0]數組,將其改成[]或[1]作爲解決方案。
 
data數組指向的內存地址,就是我們存放自定義消息數據的地方。以動態緩衝區的方式。
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章