当前位置: 首页 > 工具软件 > APR > 使用案例 >

APR学习-消息池的设计与使用

郎吉星
2023-12-01
一、任务消息的抽象池,用于从中分配任务消息
/** 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数组指向的内存地址,就是我们存放自定义消息数据的地方。以动态缓冲区的方式。
 
 
 
 
 类似资料: