前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >工作队列

工作队列

作者头像
开源519
发布2020-07-28 15:46:01
9290
发布2020-07-28 15:46:01
举报
文章被收录于专栏:开源519开源519

简介

工作队列就是内核中延后工作的一种方式,延后工作在无数场景都可以反复调度使用。

数据结构组成

代码语言:javascript
复制
/* @data: func的参数
 * @entry: 连接工作的指针
 * @func: 工作处理函数
 */
struct work_struct {
    atomic_long_t data; 
    struct list_head entry;
    work_func_t func;
#ifdef CONFIG_LOCKDEP
    struct lockdep_map lockdep_map;
#endif
};

使用流程

API 路径:kernel/kernel/workqueue.c; kernel/include/linux/workqueue.h

创建一个工作队列: a. 创建一个服务于单个CPU的工作队列

代码语言:javascript
复制
/*  @name:队列名
 *  RETURNS: Pointer to the allocated workqueue on success, %NULL on failure.
 */
create_singlethread_workqueue(name);

b. 在每一个CPU上创建一个工作队列

代码语言:javascript
复制
/* @name:队列名
 * RETURNS: Pointer to the allocated workqueue on success, %NULL on failure.
 */
create_workqueue(name);

相对于create_singlethread_workqueue, create_workqueue同样会分配一个wq的工作队列,但是不同之处在于,对于多CPU系统而言,对每一个CPU,都会为之创建一个per-CPU的cwq结构,对应每一个cwq,都会生成一个新的worker_thread进程。但是当用queue_work向cwq上提交work节点时,是哪个CPU调用该函数,那么便向该CPU对应的cwq上的worklist上增加work节点。

初始化工作项 a. 动态注册

代码语言:javascript
复制
//kernel/include/linux/workqueue.h
INIT_WORK(_work, _func) 

b. 静态注册

代码语言:javascript
复制
//kernel/include/linux/workqueue.h
DECLARE_WORK(_work, _func)  

使用静态注册可以省略定义_work,且DECLARE_WORK需要放在代码头部预处理。

运行指定工作项 a. 自定义队列运行queue_work

代码语言:javascript
复制
/* @wq: workqueue to use
 * @work: work to queue
 * Returns %false if @work was already on a queue, %true otherwise.
 */
queue_work(struct workqueue_struct *wq, struct work_struct *work)

b. 系统工作队列运行schedule_work

代码语言:javascript
复制
/* @work: 工作项
 * Returns %false if @work was already on the kernel-global workqueue and %true otherwise.
 */
schedule_work(struct work_struct *work)

queue_work,使用自定义队列运行工作项 schedule_work,调用系统的工作队列运行工作项。

小结:

一般情况下,需要指定情况多次重复调用工作项,选择定时器+queue_work。如果是指定情况下调用一次,则使用schedule_work,利用系统的工作队列执行需要的工作项。

使用流程

代码语言:javascript
复制
1.声明变量
struct test_work_dev work_dev;
static struct workqueue_struct *  test1_workqueue = NULL;

2.声明回调函数
void test1_callback(struct work_struct *work);

3.初始化队列项
#if defined (DECLARE_WORK_SUPPORT )
static DECLARE_WORK(test1_item, (void *) test1_callback);
#endif

#if !defined(DECLARE_WORK_SUPPORT)
static struct work_struct test1_item;
test1_workqueue = create_singlethread_workqueue("test1_wq");    
INIT_WORK(&test1_item, test1_callback);
#endif

4.定义回调
void test1_callback(struct work_struct *work) 
{
    printk("test1_callback!");
}

5.调度
queue_work(test1_workqueue, &test1_item);

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源519 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档