文章目录
深入剖析:高性能事件队列的设计艺术
1. 数据结构设计
1.1 关键数据结构定义
// 事件处理函数类型定义
typedef int (*event_handler_t)(void *event_data, unsigned int size);
// 结果回调函数类型定义
typedef void (*result_callback_t)(int result, void *event_data);
// 事件结构
typedef struct sl_event {
struct list_head list; // 链表节点
event_handler_t event_handler; // 事件处理函数
void *event_data; // 事件数据
unsigned int data_size; // 数据大小
result_callback_t result_callback; // 结果回调函数
event_priority_t priority; // 事件优先级
} sl_event_t;
// 事件队列结构
typedef struct sl_event_queue {
struct list_head head; // 事件链表头
pthread_mutex_t mutex; // 互斥锁
pthread_cond_t cond; // 条件变量
int running; // 运行状态
sl_event_stats_t stats; // 统计信息
unsigned int max_queue_size; // 最大队列大小
} sl_event_queue_t;
分析:
- 事件结构设计巧妙,既包含基本的事件信息,又支持回调机制
- 队列结构采用链表实现,支持动态增长
- 使用互斥锁和条件变量实现线程同步
- 包含统计信息,便于监控和调试
2. 内存管理实现
2.1 事件池设计
#define EVENT_POOL_SIZE 32
static sl_event_t event_pool[EVENT_POOL_SIZE];
static int event_pool_used[EVENT_POOL_SIZE] = {0};
static pthread_mutex_t pool_mutex = PTHREAD_MUTEX_INITIALIZER;
static sl_event_t* event_alloc(void) {
pthread_mutex_lock(&pool_mutex);
for(int i = 0; i < EVENT_POOL_SIZE; i++) {
if(!event_pool_used[i]) {
event_pool_used[i] = 1;
pthread_mutex_unlock(&pool_mutex);
return &event_pool[i];
}
}
pthread_mutex_unlock(&pool_mutex);
return NULL;
}
static void event_free(sl_event_t *event) {
if(!event) {
EVENT_LOG_ERROR("event is NULL\r\n");
return;
}
pthread_mutex_lock(&pool_mutex);
int index = (event - event_pool);
if(index >= 0 && index < EVENT_POOL_SIZE) {
event_pool_used[index] = 0;
}
pthread_mutex_unlock(&pool_mutex);
}
分析:
- 使用静态数组实现事件池,避免动态内存分配
- 通过位图管理事件对象的使用状态
- 分配和释放操作都是O(1)复杂度
- 使用互斥锁保证线程安全
3. 事件队列核心操作
3.1 队列初始化
static void event_queue_init(sl_event_queue_t *queue) {
if(!queue) {
EVENT_LOG_ERROR("queue is NULL\r\n");
return;
}
INIT_LIST_HEAD(&queue->head);
pthread_mutex_init(&queue->mutex, NULL);
pthread_cond_init(&queue->cond, NULL);
queue->running = 1;
memset(&queue->stats, 0, sizeof(sl_event_stats_t));
queue->max_queue_size = 1024;
}
分析:
- 初始化链表头
- 创建同步原语(互斥锁和条件变量)
- 设置运行状态和统计信息
- 设置默认最大队列大小
3.2 事件入队实现
static event_error_t event_queue_add_prio(sl_event_queue_t *queue, sl_event_t *new_event) {
if(!queue || !new_event) {
EVENT_LOG_ERROR("Invalid queue or event\r\n");
return EVENT_INVALID_PARAM;
}
unsigned int queue_size = 0;
struct list_head *pos;
pthread_mutex_lock(&queue->mutex);
// 检查队列大小
list_for_each(pos, &queue->head) {
queue_size++;
}
if(queue_size >= queue->max_queue_size) {
pthread_mutex_unlock(&queue->mutex);
queue->stats.queue_full_count++;
return EVENT_QUEUE_FULL;
}
// 按优先级插入
list_for_each(pos, &queue->head) {
sl_event_t *event = list_entry(pos, sl_event_t, list);
if(new_event->priority <= event->priority) {
list_add(&new_event->list, pos->prev);
queue->stats.total_events++;
pthread_cond_signal(&queue->cond);
pthread_mutex_unlock(&queue->mutex);
return EVENT_SUCCESS;
}
}
// 如果没找到合适位置,添加到队尾
list_add_tail(&new_event->list, &queue->head);
queue->stats.total_events++;
pthread_cond_signal(&queue->cond);
pthread_mutex_unlock(&queue->mutex);
return EVENT_SUCCESS;
}
分析:
- 优先级队列实现,高优先级事件优先处理
- 队列满时返回错误,防止内存溢出
- 使用条件变量通知处理线程
- 更新统计信息
3.3 事件处理实现
static void process_events(sl_event_queue_t *queue) {
struct list_head *pos, *next;
sl_event_t *curr_event;
struct list_head local_list;
INIT_LIST_HEAD(&local_list);
pthread_mutex_lock(&queue->mutex);
if (!list_empty(&queue->head)) {
list_splice_init(&queue->head, &local_list);
}
pthread_mutex_unlock(&queue->mutex);
list_for_each_safe(pos, next, &local_list) {
curr_event = list_entry(pos, sl_event_t, list);
list_del(pos);
if (curr_event->event_handler) {
int result = curr_event->event_handler(curr_event->event_data,
curr_event->data_size);
if (result == 0) {
queue->stats.processed_events++;
} else {
queue->stats.failed_events++;
}
if (curr_event->result_callback) {
curr_event->result_callback(result, curr_event->event_data);
}
}
event_free(curr_event);
}
}
分析:
- 使用本地队列批量处理事件,减少锁竞争
- 支持事件处理结果回调
- 自动释放已处理的事件
- 维护处理成功和失败的统计信息
4. 线程管理
4.1 处理线程实现
static void *event_handler_thread_enter(void *arg) {
sl_event_queue_t *queue = (sl_event_queue_t *)arg;
while (queue->running) {
pthread_mutex_lock(&queue->mutex);
while (list_empty(&queue->head) && queue->running) {
pthread_cond_wait(&queue->cond, &queue->mutex);
}
pthread_mutex_unlock(&queue->mutex);
if (queue->running) {
process_events(queue);
}
}
return NULL;
}
分析:
- 使用条件变量等待新事件
- 支持优雅退出
- 批量处理队列中的事件
- 避免了忙等待,提高CPU利用率
5. 模块接口
5.1 核心API实现
EVENT_API void sl_event_queue_module_init(void) {
event_queue_iface_t *t = &event_queue_iface;
if (t->init) {
t->init(&t->event_queue);
pthread_create(&t->thread_id, NULL, event_handler_thread_enter, &t->event_queue);
}
}
EVENT_API event_error_t sl_event_queue_add(sl_event_t *new_event) {
event_queue_iface_t *t = &event_queue_iface;
if (t->add) {
return t->add(&t->event_queue, new_event);
}
EVENT_LOG_ERROR("Failed to add event\r\n");
return EVENT_INVALID_PARAM;
}
EVENT_API void sl_event_queue_module_shutdown(void) {
event_queue_iface_t *t = &event_queue_iface;
t->event_queue.running = 0;
pthread_cond_signal(&t->event_queue.cond);
pthread_join(t->thread_id, NULL);
if (t->destroy) {
t->destroy(&t->event_queue);
}
}
分析:
- 接口设计简洁清晰
- 支持模块的初始化和清理
- 提供事件添加的标准接口
- 实现了优雅的退出机制
6. 总结
事件队列模块的实现具有以下特点:
- 内存管理高效,使用静态事件池
- 线程同步机制完善,支持优先级调度
- 接口设计合理,易于使用和扩展
- 性能优化到位,支持批量处理
- 可靠性高,包含完整的错误处理和统计功能
建议优化方向:
- 添加事件超时机制
- 实现事件过滤功能
- 支持动态调整队列大小
- 增加性能监控接口