Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >工作队列

工作队列

作者头像
开源519
发布于 2020-07-28 07:46:01
发布于 2020-07-28 07:46:01
1K00
代码可运行
举报
文章被收录于专栏:开源519开源519
运行总次数:0
代码可运行

简介

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

数据结构组成

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* @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
代码运行次数:0
运行
AI代码解释
复制
/*  @name:队列名
 *  RETURNS: Pointer to the allocated workqueue on success, %NULL on failure.
 */
create_singlethread_workqueue(name);

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* @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
代码运行次数:0
运行
AI代码解释
复制
//kernel/include/linux/workqueue.h
INIT_WORK(_work, _func) 

b. 静态注册

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//kernel/include/linux/workqueue.h
DECLARE_WORK(_work, _func)  

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* @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
代码运行次数:0
运行
AI代码解释
复制
/* @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
代码运行次数:0
运行
AI代码解释
复制
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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Linux设备驱动workqueue(工作队列)案例实现
工作队列(work queue)是另外一种将工作推后执行的形式,tasklet(小任务机制)有所不同。工作队列可以把工作推后,交由一个内核线程去执行,也就是说,这个下半部分可以在进程上下文中执行。这样,通过工作队列执行的代码能占尽进程上下文的所有优势。最重要的就是工作队列允许被重新调度甚至是睡眠。
杨源鑫
2019/07/04
5.5K0
并发设计模式实战系列(3):工作队列
今天为大家带来的是并发设计模式实战系列,第三章工作队列(Work Queue)​​,废话不多说直接开始~
摘星编程
2025/05/20
840
Linux内核中的软中断、tasklet和工作队列具体解释
软中断、tasklet和工作队列并非Linux内核中一直存在的机制,而是由更早版本号的内核中的“下半部”(bottom half)演变而来。
全栈程序员站长
2022/07/20
2.4K0
Linux内核中的软中断、tasklet和工作队列具体解释
异步处理的强力助手:Linux Workqueue 机制详解
“ 在 Linux 内核中,workqueue 是一个重要的机制,用于处理那些不紧急且适合异步执行的任务。本文将详细介绍 workqueue 的基本概念及其在中断处理中的作用,揭示其如何通过后台线程提高系统的响应速度和性能。探讨 workqueue 的实现原理、创建与销毁过程,并讨论如何通过该机制优化系统任务调度。”
Lion 莱恩呀
2024/08/01
7180
异步处理的强力助手:Linux Workqueue 机制详解
workqueue
在之前的softirq中提到过,内核在中断的bottom half引入了softirq, tasklet, workqueue。 而softirq和tasklet只能用在中断上下文中,而且不可以睡眠。所以内核引入了workqueue,工作队列运行在进程上下文,同时可以睡眠。在以前版本的内核中workqueue的代码比较简单。在linux2.6.30代码量在1000行左右,而在linux3.18代码量在5000行左右。其中巨大的变化就是引入了Concurrency Managed Workqueue (cmwq)概念。不过本篇先学习以前版本的workqueue,因为它简单。在了解了简单版本的存在问题之后在学习cmwq就有更好的认识。
DragonKingZhu
2020/03/24
1.2K0
万字整理 | 深入理解工作队列
伟林,中年码农,从事过电信、手机、安全、芯片等行业,目前依旧从事Linux方向开发工作,个人爱好Linux相关知识分享,个人微博CSDN pwl999,欢迎大家关注! 1.1 worker_pool 1.1.1 normal worker_pool 1.1.2 unbound worker_pool 1.2 worker 1.2.1 worker处理work 1.2.2 worker_pool动态管理worker 1.2.3 cpu hotplug处理 1.3 workqueue 1.3.1 系统workq
刘盼
2022/08/26
1.9K0
万字整理 | 深入理解工作队列
45.INIT_WORK()工作队列使用
中断中通过调用schedule_work(work)来通知内核线程,然后中断结束后,再去继续执行work对应的func函数
诺谦
2018/09/30
5.7K0
Linux驱动实践:中断处理中的【工作队列】 workqueue 是什么鬼?
大家好,我是道哥,今天我为大伙儿解说的技术知识点是:【中断处理中的下半部分机制-工作队列】。
IOT物联网小镇
2021/12/28
2.1K0
Linux驱动实践:中断处理中的【工作队列】 workqueue 是什么鬼?
Linux的中断下半部机制的对比
 中断服务程序一般都是在中断请求关闭的条件下执行的,以避免嵌套而使中断控制复杂化。但是,中断是一个随机事件,它随时会到来,如果关中断的时间太长,CPU就不能及时响应其他的中断请求,从而造成中断的丢失。因此,Linux内核的目标就是尽可能快的处理完中断请求,尽其所能把更多的处理向后推迟。例如,假设一个数据块已经达到了网线,当中断控制器接受到这个中断请求信号时,Linux内核只是简单地标志数据到来了,然后让处理器恢复到它以前运行的状态,其余的处理稍后再进行(如把数据移入一个缓冲区,接受数据的进程就可以在缓冲区找到数据)。因此,内核把中断处理分为两部分:上半部(tophalf)和下半部(bottomhalf),上半部(就是中断服务程序)内核立即执行,而下半部(就是一些内核函数)留着稍后处理。
灯珑LoGin
2024/02/06
5170
Linux的中断下半部机制的对比
Linux内核23-工作队列
Linux2.6版本中引入了工作队列概念,代替Linux2.4版本中的任务队列。用以实现注册激活某些函数,留待稍后由工作线程执行(与tasklet的处理类似)。
Tupelo
2022/08/15
1.2K0
Linux驱动开发-内核共享工作队列
工作队列常见的使用形式是配合中断使用,在中断的服务函数里无法调用会导致休眠的相关函数代码,有了工作队列机制以后,可以将需要执行的逻辑代码放在工作队列里执行,只需要在中断服务函数里触发即可,工作队列是允许被重新调度、睡眠。
DS小龙哥
2022/04/08
2.1K0
linux大量kworker_linux load average 非常高
最近遇到一个kworker问题,callstack如下,线程adas的陷入kernel space后会schedule_work调用一个while(1)的worker,kill adas后重新启动adas后adas线程会在调用dma_alloc_coherent的时候block住
全栈程序员站长
2022/11/08
3.8K0
linux大量kworker_linux load average 非常高
扒开 Linux 中断的底裤之 workqueue
workqueue 是除了 softirq 和 tasklet 以外最常用的下半部机制之一。workqueue 的本质是把 work 交给一个内核线程,在进程上下文调度的时候执行。因为这个特点,所以 workqueue 允许重新调度和睡眠,这种异步执行的进程上下文,能解决因为 softirq 和 tasklet 执行时间长而导致的系统实时性下降等问题。
刘盼
2021/08/25
2.3K0
扒开 Linux 中断的底裤之 workqueue
[ Linux驱动炼成记 ] 12 -音频驱动TAS5754添加EQ参数
每一个带有音频播放的产品,设备初期的时候都会调试设备的EQ参数。EQ通过将声音中各频率的组成泛音等级加以修改,专为某一类音乐进行优化,增强人们的感觉。常见包括:正常、摇滚、流行、舞曲、古典、柔和、爵士、金属、重低音和自定义。1
程序手艺人
2019/02/20
1.4K0
Linux中断下半部实现机制
由于内核中中断不允许嵌套,在程序进入中断后,系统会关闭中断接收,这段时间内,其他中断都无法处理导致中断无法响应,因此需要当前进入的中断子服务函数越快越好。但是在一些特殊情况下,中断要处理的事情可能是复杂且冗长的,为解决这种问题, 中断上下半部的概念顺势而生。将中断拆成两部分,上半部用来处理紧急的事情;下半部用来处理不紧急的事情。
开源519
2020/07/23
3.3K0
zephyr 工作队列(work queue)
zephyr中工作队列是基于线程的,简单来说,就是有一个线程一直在等待工作队列的api发来的工作项,当有工作项时(一个待 执行的函数)就处理(把函数调用了),当有多个工作项时就按顺序处理,没有工作项时就休眠。
无限之生
2020/07/01
1.4K0
SDIO接口WiFi驱动浅析[通俗易懂]
SDIO-Wifi模块是基于SDIO接口的符合wifi无线网络标准的嵌入式模块,内置无线网络协议IEEE802.11协议栈以及TCP/IP协议栈,能够实现用户主平台数据通过SDIO口到无线网络之间的转换。SDIO具有传输数据快,兼容SD、MMC接口等特点。
全栈程序员站长
2022/11/09
7.4K0
SDIO接口WiFi驱动浅析[通俗易懂]
使用工作队列管理器(三)
一个类别是一个独立的worker jobs池。当初始化一组worker jobs时,可以指定提供worker的类别。如果集合中的任何worker jobs在执行work项时请求额外的worker jobs,则新的worker jobs来自同一类别。
用户7741497
2022/08/03
4790
吐血整理 | 肝翻 Linux 中断所有知识点
GIC,Generic Interrupt Controller。是ARM公司提供的一个通用的中断控制器。主要作用为:接受硬件中断信号,并经过一定处理后,分发给对应的CPU进行处理。
刘盼
2021/08/25
4.1K1
吐血整理 | 肝翻 Linux 中断所有知识点
Linux驱动开发-编写FT5X06触摸屏驱动
这篇文章介绍在Linux下如何编写FT5X06系列芯片驱动,完成触摸屏的驱动开发, FT5X06是一个系列,当前使用的具体型号是FT5206,它是一个电容屏的触摸芯片,内置了8位的单片机(8051内核),完成了坐标换算等很多处理,在通过IIC,SPI方式传递给外部单片机。
DS小龙哥
2022/04/08
2.8K0
Linux驱动开发-编写FT5X06触摸屏驱动
相关推荐
Linux设备驱动workqueue(工作队列)案例实现
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验