21 工作队列
工作队列内部有一个工作链表(worklist),链表上有多个工作项(work item)节点,我们可以将工作项简单理解为函数,因此工作链表上就存储着一系列待执行的函数。而且工作队列内有个线程一直在轮询工作链表,每次都从工作链表中取出一个工作项,并执行其相关联的函数。当工作队列为空时,线程会被挂起。
/* workqueue implementation */
struct rt_workqueue
{
rt_list_t work_list;
rt_list_t delayed_list;
struct rt_work *work_current; /* current work */
struct rt_semaphore sem;
rt_thread_t work_thread;
struct rt_spinlock spinlock;
};
struct rt_work
{
rt_list_t list;
void (*work_func)(struct rt_work *work, void *work_data);
void *work_data;
rt_uint16_t flags;
rt_uint16_t type;
struct rt_timer timer;
struct rt_workqueue *workqueue;
};
21.1 初始化
- 创建工作队列
- 分配工作队列内存
- 初始话队列链表和延迟链表;信号量
- 创建线程
_workqueue_thread_entry
,并启动线程
- 创建工作项
- 初始化工作项链表,注册回调函数及数据指针
21.2 提交工作项
- 删除列表
- 有定时时间
- 根据工作项是否已经发送状态,进行定时器定时操作
- 将工作项插入到工作队列延时链表中,开启定时器
- 没有定时时间
21.3 工作队列线程
- while循环
- 队列为空,挂起线程,产生调度;等待队列有工作项
- 从队列中取出工作项,执行回调函数,删除该工作项
21.4 定时器超时
- 将工作项从延时链表中移除,插入工作链表中
21.5 信号量作用
-rt_workqueue_cancel_work_sync
- 执行时判断当前工作项是要取消工作项,则获取信号量,阻塞等待工作项执行完成
- 工作线程中
_workqueue_work_completion
- 执行完成后,获取信号量;注意,因为执行完成后工作项自动删除,所以不需要再次删除
- 如果信号量阻塞超时,证明需要释放信号量,通知
rt_workqueue_cancel_work_sync
取消工作项 - 没有超时,则开始下一个工作项