工作队列

工作队列内部有一个工作链表(worklist),链表上有多个工作项(work item)节点,我们可以将工作项简单理解为函数,因此工作链表上就存储着一系列待执行的函数。而且工作队列内有个线程一直在轮询工作链表,每次都从工作链表中取出一个工作项,并执行其相关联的函数。当工作队列为空时,线程会被挂起。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

/* 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;

};

初始化

  • 创建工作队列
  1. 分配工作队列内存
  2. 初始话队列链表和延迟链表;信号量
  3. 创建线程 _workqueue_thread_entry,并启动线程
  • 创建工作项
  1. 初始化工作项链表,注册回调函数及数据指针

提交工作项

  1. 删除列表
  2. 有定时时间
  • 根据工作项是否已经发送状态,进行定时器定时操作
  • 将工作项插入到工作队列延时链表中,开启定时器
  1. 没有定时时间

工作队列线程

  1. while循环
  2. 队列为空,挂起线程,产生调度;等待队列有工作项
  3. 从队列中取出工作项,执行回调函数,删除该工作项

定时器超时

  1. 将工作项从延时链表中移除,插入工作链表中

信号量作用

-rt_workqueue_cancel_work_sync

  1. 执行时判断当前工作项是要取消工作项,则获取信号量,阻塞等待工作项执行完成
  • 工作线程中 _workqueue_work_completion
  1. 执行完成后,获取信号量;注意,因为执行完成后工作项自动删除,所以不需要再次删除
  2. 如果信号量阻塞超时,证明需要释放信号量,通知 rt_workqueue_cancel_work_sync取消工作项
  3. 没有超时,则开始下一个工作项