任务调度器
ElenixOS 任务调度器是一个轻量级的任务队列系统,专为在非实时上下文中延迟执行回调函数而设计。它提供了一种简单有效的机制,用于在适当的时机执行需要在特定线程(如 GUI 线程)中运行的任务。
核心特性
- 线程安全:内部使用信号量保护队列操作,支持从任意线程或中断中调用
- 动态扩容:队列容量不足时会自动翻倍扩容,确保任务不会丢失
- 轻量设计:最小化内存占用和执行开销
- 环形队列:采用环形队列实现,高效管理任务
API 参考
初始化
eos_dispatcher_init():初始化任务调度器,必须在 GUI 线程启动前或系统初始化阶段调用- 初始队列容量为 8
- 创建用于线程同步的信号量
- 分配初始队列内存
任务管理
-
eos_dispatcher_call(eos_dispatcher_cb_t cb, void *user_data):将回调函数加入队列- 参数:
cb:要执行的回调函数user_data:传递给回调函数的用户数据
- 特性:
- 从任意线程或中断中调用,执行时间短
- 队列满时自动尝试扩容
- 扩容失败时会静默丢弃任务(内存分配失败)
- 参数:
-
eos_dispatch_tick():处理队列中的所有待执行任务- 在 GUI 线程循环中定期调用
- 依次执行队列中的所有回调函数
- 执行过程中会释放信号量,允许其他线程继续添加任务
工作原理
- 队列结构:使用环形队列存储任务,包含回调函数指针和用户数据
- 线程同步:通过信号量保证多线程操作的安全性
- 内存管理:初始分配固定大小的队列,容量不足时自动扩容
- 执行机制:在
eos_dispatch_tick()调用时,按顺序执行队列中的所有任务
使用场景
- 中断处理:在中断中收集事件,将实际处理逻辑推迟到主循环执行
- 耗时操作:避免在中断或高优先级任务中执行耗时操作
- 跨线程通信:提供一种轻量级的跨线程任务提交机制
- 异步执行:实现简单的异步操作,无需完整的 RTOS 调度
注意事项
- 初始化顺序:必须在使用前调用
eos_dispatcher_init()进行初始化 - LVGL 安全:
eos_dispatcher_call()支持任意线程调用,但回调函数中如果需要操作 LVGL,应确保在 GUI 线程中执行 - 与
lv_call_async()的区别:lv_call_async()仅支持 GUI 线程调用,而eos_dispatcher_call()支持任意线程调用 - 内存使用:队列会自动扩容,但频繁的扩容可能导致内存碎片,建议根据实际需求预估合适的初始容量
- 错误处理:当内存分配失败时,任务可能被静默丢弃,应在关键场景中考虑错误处理