Linux 工作队列(Workqueue):概念与实现
目录
- 一、工作队列的概念
- 1.1 什么是工作队列
- 1.2 为什么使用工作队列
- 二、工作队列的实现
- 2.1 定义和初始化工作队列
- 2.2 工作队列API
- 三、工作队列的应用
- 3.1 延迟执行任务
- 3.2 处理复杂的中断任务
- 四、工作队列的类型
- 4.1 普通工作队列
- 4.2 高优先级工作队列
- 五、总结
在Linux内核中,工作队列(Workqueue)是一种用于延迟任务执行的机制。它允许内核代码在可中断上下文中执行任务,这对于需要在进程上下文中运行或者需要延迟执行的任务非常有用。在本文中,我们将详细介绍工作队列的概念、实现以及实际应用。
一、工作队列的概念
1.1 什么是工作队列
工作队列(Workqueue)是Linux内核提供的一种机制,用于将任务推迟到将来某个时间点在进程上下文中执行。与软中断和任务队列不同,工作队列允许任务在进程上下文中运行,这意味着它们可以睡眠和使用所有的内核API。
1.2 为什么使用工作队列
使用工作队列的主要原因是一些任务需要在中断上下文之外执行。中断处理程序通常需要尽可能快地完成,以避免延迟其他中断的处理。然而,有些任务需要较长的时间来完成,或者需要使用可能会睡眠的内核API。在这种情况下,可以使用工作队列将这些任务推迟到稍后在进程上下文中执行。
二、工作队列的实现
2.1 定义和初始化工作队列
在Linux内核中,工作队列由struct workqueue_struct
表示,工作项由struct work_struct
表示。你可以使用create_workqueue
函数创建一个新的工作队列,并使用INIT_WORK
宏初始化一个工作项。
struct workqueue_struct *my_wq;
struct work_struct my_work;void my_work_function(struct work_struct *work) {printk(KERN_INFO "Workqueue: Task executed\n");
}static int __init my_module_init(void) {my_wq = create_workqueue("my_workqueue");if (my_wq) {INIT_WORK(&my_work, my_work_function);queue_work(my_wq, &my_work);}return 0;
}static void __exit my_module_exit(void) {flush_workqueue(my_wq);destroy_workqueue(my_wq);
}module_init(my_module_init);
module_exit(my_module_exit);
2.2 工作队列API
以下是一些常用的工作队列API:
create_workqueue
:创建一个新的工作队列。destroy_workqueue
:销毁工作队列。INIT_WORK
:初始化一个工作项。queue_work
:将工作项添加到工作队列中。flush_workqueue
:等待工作队列中的所有工作项完成。cancel_work_sync
:取消一个工作项的执行。
三、工作队列的应用
3.1 延迟执行任务
工作队列非常适合需要延迟执行的任务。例如,在驱动程序中,可以使用工作队列来处理需要延迟执行的任务,如处理硬件中断或定期检查设备状态。
示例:延迟执行任务
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/workqueue.h>
#include <linux/delay.h>static struct workqueue_struct *my_wq;
static struct delayed_work my_delayed_work;void my_delayed_work_function(struct work_struct *work) {printk(KERN_INFO "Delayed Workqueue: Task executed after delay\n");
}static int __init my_module_init(void) {my_wq = create_workqueue("my_delayed_workqueue");if (my_wq) {INIT_DELAYED_WORK(&my_delayed_work, my_delayed_work_function);queue_delayed_work(my_wq, &my_delayed_work, msecs_to_jiffies(5000)); // 延迟5秒执行}return 0;
}static void __exit my_module_exit(void) {cancel_delayed_work_sync(&my_delayed_work);destroy_workqueue(my_wq);
}module_init(my_module_init);
module_exit(my_module_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("OpenAI GPT-4");
MODULE_DESCRIPTION("A simple example of using workqueue with delayed execution in Linux kernel.");
3.2 处理复杂的中断任务
在中断处理程序中,我们通常尽量减少执行时间,以免阻塞其他中断。对于需要较长时间处理的任务,可以使用工作队列来延迟执行。
示例:在中断处理程序中使用工作队列
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>static struct workqueue_struct *my_wq;
static struct work_struct my_work;irqreturn_t my_interrupt_handler(int irq, void *dev_id) {queue_work(my_wq, &my_work);return IRQ_HANDLED;
}void my_work_function(struct work_struct *work) {printk(KERN_INFO "Workqueue: Handling interrupt task\n");
}static int __init my_module_init(void) {int irq = 1; // 假设使用 IRQ 1my_wq = create_workqueue("my_interrupt_workqueue");if (my_wq) {INIT_WORK(&my_work, my_work_function);request_irq(irq, my_interrupt_handler, IRQF_SHARED, "my_interrupt_handler", NULL);}return 0;
}static void __exit my_module_exit(void) {int irq = 1; // 假设使用 IRQ 1free_irq(irq, NULL);flush_workqueue(my_wq);destroy_workqueue(my_wq);
}module_init(my_module_init);
module_exit(my_module_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("OpenAI GPT-4");
MODULE_DESCRIPTION("A simple example of using workqueue in interrupt handler in Linux kernel.");
四、工作队列的类型
Linux内核提供了两种类型的工作队列:
4.1 普通工作队列
普通工作队列使用默认的系统工作队列来执行任务。示例中的create_workqueue
就是创建一个普通工作队列。
4.2 高优先级工作队列
在某些情况下,需要更高优先级的工作队列来执行关键任务。Linux内核提供了高优先级工作队列,可以通过alloc_workqueue
函数创建。
示例:创建高优先级工作队列
static struct workqueue_struct *my_highpri_wq;static int __init my_module_init(void) {my_highpri_wq = alloc_workqueue("my_highpri_workqueue", WQ_HIGHPRI, 0);if (my_highpri_wq) {INIT_WORK(&my_work, my_work_function);queue_work(my_highpri_wq, &my_work);}return 0;
}static void __exit my_module_exit(void) {flush_workqueue(my_highpri_wq);destroy_workqueue(my_highpri_wq);
}
五、总结
工作队列(Workqueue)是Linux内核中用于延迟执行任务的一种机制。它允许任务在进程上下文中运行,使得任务可以睡眠并使用所有的内核API。本文详细介绍了工作队列的概念、实现以及实际应用,并提供了多个示例代码。通过这些知识和示例,相信你能够在内核开发中更好地使用工作队列来管理延迟任务。
相关文章:
Linux 工作队列(Workqueue):概念与实现
目录 一、工作队列的概念1.1 什么是工作队列1.2 为什么使用工作队列 二、工作队列的实现2.1 定义和初始化工作队列2.2 工作队列API 三、工作队列的应用3.1 延迟执行任务3.2 处理复杂的中断任务 四、工作队列的类型4.1 普通工作队列4.2 高优先级工作队列 五、总结 在Linux内核中…...
前端页面是如何禁止被查看源码、被下载,被爬取,以及破解方法
文章目录 1.了解禁止查看,爬取原理1.1.JS代码,屏蔽屏蔽键盘和鼠标右键1.2.查看源码时,通过JS控制浏览器窗口变化2.百度文库是如何防止抓包2.1.HTPPS2.2. 动态加载为什么看不到?如何查看动态加载的内容?3.禁止复制,如果解决3.1.禁止复制原理3.2.如何破解1.了解禁止查看,爬…...
51单片机嵌入式开发:14、STC89C52RC 之HX1838红外解码NEC+数码管+串口打印+LED显示
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 STC89C52RC 之HX1838红外解码NEC数码管串口打印LED显示 STC89C52RC 之HX1838红外解码NEC数码管串口打印LED显示1 概述2 硬件电路2.1 遥控器2.2 红外接收器电路2.3 STC89C52单…...
在不同环境中,Java应用程序和MySQL等是如何与Docker进行交互和操作的?
1. 本地开发环境 在本地开发环境中,可以使用Docker Compose来管理和运行Java应用程序容器和MySQL容器。通常,会创建一个docker-compose.yml文件,定义需要的服务及其配置。 以下是一个示例docker-compose.yml文件: version: 3 services:app…...
《DRL》P10-P15-损失函数-优化(梯度下降和误差的反向传播)
文章目录 损失函数交叉熵损失多类别分类任务概述真实标签的独热编码交叉熵损失函数 L p 范式 \mathcal{L}_{p}\text{ 范式} Lp 范式均方误差平均绝对误差 优化梯度下降和误差的反向传播 简介 本文介绍了神经网络中的损失函数及其优化方法。损失函数用于衡量模型预测值与真实值…...
Spring Boot项目的404是如何发生的
问题 在日常开发中,假如我们访问一个Sping容器中并不存在的路径,通常会返回404的报错,具体原因是什么呢? 结论 错误的访问会调用两次DispatcherServlet:第一次调用无法找到对应路径时,会给Response设置一个…...
<数据集>手势识别数据集<目标检测>
数据集格式:VOCYOLO格式 图片数量:2400张 标注数量(xml文件个数):2400 标注数量(txt文件个数):2400 标注类别数:5 标注类别名称:[fist, no_gesture, like, ok, palm] 序号类别名称图片数框数1fist597…...
【Vue3】选项式 API
【Vue3】选项式 API 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。…...
2、如何发行自己的数字代币(truffle智能合约项目实战)
2、如何发行自己的数字代币(truffle智能合约项目实战) 1-Atom IDE插件安装2-truffle tutorialtoken3-tutorialtoken源码框架分析4-安装openzeppelin代币框架(代币发布成功) 1-Atom IDE插件安装 正式介绍基于web的智能合约开发 推…...
百日筑基第二十三天-23种设计模式-创建型总汇
百日筑基第二十三天-23种设计模式-创建型总汇 前言 设计模式可以说是对于七大设计原则的实现。 总体来说设计模式分为三大类: 创建型模式,共五种:单例模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式。结构型模式,共…...
张量的基本使用
目录 1.张量的定义 2.张量的分类 3.张量的创建 3.1 根据已有数据创建张量 3.2 根据形状创建张量 3.3 创建指定类型的张量 1.张量的定义 张量(Tensor)是机器学习的基本构建模块,是以数字方式表示数据的形式。PyTorch就是将数据封装成张量…...
Oracle(14)什么是唯一键(Unique Key)?
唯一键(Unique Key)是数据库表中的一个或多个列,它们的值必须在整个表中唯一,但允许包含NULL值。唯一键的主要目的是确保表中每一行的数据在指定的列(或列组合)中是唯一的,以防止重复数据的出现…...
PostgreSQL的引号、数据类型转换和数据类型
一、单引号和双引号(重要): 1、在mysql没啥区别 2、在pgsql中,实际字符串用单引号,双引号相当于mysql的,用来包含关键字; -- 单引号,表示user_name的字符串实际值 insert into t_user(user_nam…...
Mad MAD Sum-Codeforces Round 960 (Div. 2)
题目在这里 大意: MAD函数返回出现次数 ≥ 2 \geq2 ≥2的最大整数 b i b_i bi M A D ( a [ 1 , 2 , . . . i ] ) MAD(a[1,2,...i]) MAD(a[1,2,...i]) 每次操作把 a i a_i ai进行上述操作,直到全变为0为止,对每次操作的数组进行求和,记…...
Flutter 插件之 package_info_plus
当使用Flutter开发应用时,通常需要获取应用程序的基本信息,例如包名、版本号和构建号。Flutter提供了一个名为 package_info_plus 的插件,它能方便地帮助我们获取这些信息。 1. 添加依赖 首先,需要在项目的 pubspec.yaml 文件中添加 package_info_plus 的依赖。打开 pubs…...
如何实现布隆过滤器?
1.布隆过滤器的场景 在Redis 缓存击穿(失效)、缓存穿透、缓存雪崩怎么解决?中我们说到可以使用布隆过滤器避免「缓存穿透」。 你会说我们只要记录了每个用户看过的历史记录,每次推荐的时候去查询数据库过滤存在的数据实现去重。 …...
运维团队如何高效监控容器化环境中的PID及其他关键指标
随着云计算和容器化技术的快速发展,越来越多的企业开始采用容器化技术来部署和管理应用程序。然而,容器化环境的复杂性和动态性给运维团队带来了前所未有的挑战。本文将从PID(进程标识符)监控入手,探讨运维团队如何高效…...
通过vue3 + TypeScript + uniapp + uni-ui 实现下拉刷新和加载更多的功能
效果图: 核心代码: <script lang="ts" setup>import { ref, reactive } from vue;import api from @/request/api.jsimport empty from @/component/empty.vueimport { onLoad,onShow, onPullDownRefresh, onReachBottom } from @dcloudio/uni-applet form …...
Pointnet++改进即插即用系列:全网首发WTConv2d大接受域的小波卷积|即插即用,提升特征提取模块性能
简介:1.该教程提供大量的首发改进的方式,降低上手难度,多种结构改进,助力寻找创新点!2.本篇文章对Pointnet++特征提取模块进行改进,加入WTConv2d,提升性能。3.专栏持续更新,紧随最新的研究内容。 目录 1.理论介绍 2.修改步骤 2.1 步骤一 2.2 步骤二 2.3 步骤三 1.理…...
4核16G服务器支持多少人?4C16G服务器性能测评
租赁4核16G服务器费用,目前4核16G服务器10M带宽配置70元1个月、210元3个月,那么能如何呢?配置为ECS经济型e实例4核16G、按固定带宽10Mbs、100GB ESSD Entry系统盘。 那么问题来了,4C16G10M带宽的云服务器可以支持多少人同时在线&…...
塔子哥的平均数-美团2023笔试(codefun2000)
题目链接 塔子哥的平均数-美团2023笔试(codefun2000) 题目内容 给定一个正整数数组a1 ,a2 ,…,an,求平均数正好等于k的最长连续子数组的长度 输入描述 输出描述 输出一个整数,表示最长满足题目条件的长度。 样例1 输入 5 2 1 3 2 4 1 输出 3 样例1解释…...
故障诊断 | 基于小波包能量谱对滚动轴承的故障诊断Matlab代码
故障诊断 | 基于小波包能量谱对滚动轴承的故障诊断Matlab代码 目录 故障诊断 | 基于小波包能量谱对滚动轴承的故障诊断Matlab代码效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于小波包能量谱对滚动轴承的故障诊断 matlab代码 数据采用的是凯斯西储大学数据 首先利用…...
E14.【C语言】练习:有关短路运算
#include <stdio.h> int main() {int i 0,a0,b2,c 3,d4;i a && b && d;printf("a %d\nb %d\nc %d\nd %d\n", a, b, c, d);return 0; } 求输出结果 分析: a:先使用后 ,a(见第15篇http://…...
python BeautifulSoup库安装与使用(anaconda、pip)
BeautifulSoup 是一个可以从HTML或XML文件中提取数据的Python库。Beautiful Soup 已成为和 lxml、html5lib 一样出色的Python解释器,为用户灵活地提供不同的解析策略或强劲的速度。 Requests 获取html BeautifulSoup 解析html、xml,BeautifulSoup4库也称bs4库 安装B…...
基于Matlab的数据可视化
基于Matlab的数据可视化 一、二维图形的绘制(一)基本图形函数(1)plot函数(2)fplot函数(3)其他坐标系的二维曲线 (二)图形属性设置(1)线…...
深入理解Linux网络(二):UDP接收内核探究
深入理解Linux网络(二):UDP接收内核探究 一、UDP 协议处理二、recvfrom 系统调⽤实现 一、UDP 协议处理 udp 协议的处理函数是 udp_rcv。 //file: net/ipv4/udp.c int udp_rcv(struct sk_buff *skb) {return __udp4_lib_rcv(skb, &udp_…...
linux内核中list的基本用法
内核链表 1 list_head 结构 为了使用链表机制,驱动程序需要包含<linux/types.h>头文件,该文件定义了如下结构体实现双向链: struct list_head {struct list_head *next, *prev; };2 链表的初始化 2.1 链表宏定义和初始化 可使用以…...
项目中无关痛痒的词句背后深层含义
项目中听上去无关痛痒的词句背后,深层含义有的时候并不友善。 他们说的:进度表有些激进 真正的意思:我们有麻烦了 他们说的:我们将在接下来的几个迭代里面弥补延误 真正的意思:我们还是有麻烦 他们说的࿱…...
DLMS协议中的高级安全(HLS)身份验证
1.四步身份验证协议 在IEC 62056-53中已说明,ACSE提供部分高级身份安全(HLS)验证服务。高级身份安全验证适用于通信通道不能提供内部安全,应采取防范措施以防止偷听和信息(密码)重现的情况。这时ÿ…...
2024“钉耙编程”杭电多校1006 序列立方(思维+前缀和优化dp)
来源 题目 Problem Description 给定长度为 N 的序列 a。 一个序列有很多个子序列,每个子序列在序列中出现了若干次。 小马想请你输出序列 a 每个非空子序列出现次数的立方值的和,答案对 998244353 取模。 你可以通过样例解释来辅助理解题意。 Input 第…...
直播带货系统/对网站的建议和优化
本文研究全球及中国市场身份和访问管理(IAM)软件现状及未来发展趋势,侧重分析全球及中国市场的主要企业,同时对比北美、欧洲、中国、日本、东南亚和印度等地区的现状及未来发展趋势。 根据QYR(恒州博智)的统…...
建设工程合同范本 政府网站/100个商业经典案例
加载图像(用cv::imread)imread功能是加载图像文件成为一个Mat对象 其中第一个参数表示图像文件名称第二个参数 表示加载的图像是什么类型 支持常见的三个参数值IMREAD_UNCHANGE(<0)表示加载原图 不做任何改变IMREAD_GRAYSCALE(0)表示把原图作为灰度图像加载进来IMREAD_COLOR…...
晋江文学城电脑版/搜索引擎排名优化公司
报道|深度学习这件小事网络上流传了一份一二线城市知名的互联网(或者说IT相关)公司名单,比较全,本文新增了一些,还有一些已经淡出圈子的就删除了,做了一些修改,相对较新。当然了&…...
网站设计数据库怎么做/刷赞网站推广免费链接
命令1 & 命令2 & 命令3 ... (无论前面命令是否故障,照样执行后面) 命令1 && 命令2 && 命令3.... (仅当前面命令成功时,才执行后面) 命令1 || 命令2 || 命令3.... (仅当前面命令失败时.才执行后面)1、start 用来启动一…...
拱墅网站建设制作/seo网站自动发布外链工具
2.2 单页面应用介绍 什么是单页应用?引用百度百科:单页面应用的优缺点:优点:1、用户操作体验好,用户不用刷新页面,整个交互过程都是通过Ajax来操作。 2、适合前后端分离开发,服务端提供http接口…...
做网站的成本/网站关键词快速排名工具
如果你是设计师,需要向客户发送设计图纸;如果你是业务员,需要向国外客户发送视频文件;如果你是工程师,需要向合作伙伴发送图纸、代码、软件包等;如果你是摄影师,需要向客户发送照片;…...