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。本文详细介绍了工作队列的概念、实现以及实际应用,并提供了多个示例代码。通过这些知识和示例,相信你能够在内核开发中更好地使用工作队列来管理延迟任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/871837.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Golang | Leetcode Golang题解之第229题多数元素II

题目&#xff1a; 题解&#xff1a; func majorityElement(nums []int) (ans []int) {cnt : map[int]int{}for _, v : range nums {cnt[v]}for v, c : range cnt {if c > len(nums)/3 {ans append(ans, v)}}return }

kaggle加载训练好的模型

kaggle加载训练好的模型 问题 已经在kaggle平台保存了&#xff08;保存在电脑本地&#xff09;一个自己训练好的模型&#xff0c;然后如何在一个新建的notebook中使用自己训练好的模型呢 解答 先确定自己使用了哪个框架的模型&#xff08;keras,pytorch,timm等&#xff09;…

找到完美的横道图工具:2024年选择指南

国内外主流的10款项目进度横道图软件对比&#xff1a;PingCode、Worktile、灵动计划&#xff08;Wolai&#xff09;、飞书项目、Tapd、麦客CRM、Asana、Trello、Smartsheet、Basecamp。 在管理项目时&#xff0c;确保所有进度和任务都按计划进行是每个项目经理面临的一大挑战。…

Excel如何才能忽略隐藏行进行复制粘贴?

你有没有遇到这样的情况&#xff1a;数据很多&#xff0c;将一些数据隐藏后&#xff0c;进行复制粘贴&#xff0c;结果发现粘贴后的内容仍然将整个数据都显示出来了&#xff01;那么&#xff0c;Excel如何才能忽略隐藏行进行复制粘贴&#xff1f; 打开你的Excel表格 Excel如何…

WordPress:无法创建新文章?创建新帖子时候页面空白

wordPress中我们新建文章的时候&#xff0c;会遇到页面空白&#xff0c;这个问题是怎么导致呢&#xff1f;我们可以打开F12开发者模式看下报错信息&#xff0c;这是一个警告信息 Warning: Creating default object from empty value in /pub 到数据库 wp_posts中查看生成了很…

力扣题解(不相交的线)

1035. 不相交的线 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在&#xff0c;可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线&#xff0c;这些直线需要同时满足&#xff1a; nums1[i] nums2[j]且绘制的直线不与任何其他连线&#xff08;非水…

漏洞挖掘 | 记某证书站任意账号接管漏洞

下文中所述漏洞已修复 在前段时间的漏洞挖掘中&#xff0c;上了某证书站&#xff0c;打点的一处逻辑漏洞 访问某一站点&#xff0c;发现了一处登录页 点击登录按钮之后&#xff0c;发现该站点大概率是自写站点&#xff0c;存在逻辑漏洞的可能性大大增大&#xff0c;利用前期信…

Android gradle groovy改为kotlin总结

前言&#xff1a; Android gradle 的 Groovy 转 Kotlin 的难点在于groovy非常不规范&#xff0c;以为是一个变量其实是一个方法&#xff0c;以为是方法其实是一个一个字符串&#xff0c;koltin提供了更严格的语法。改为kotlin之后最大的变化就是扩展字段了&#xff0c;和groovy…

CentOS7配置阿里云yum源

前提&#xff1a;确认机器可以连接互联网&#xff0c;且系统已经安装了wget软件 先进入到/etc/yum.repos.d目录下查看是否有原来的yum源配置文件&#xff0c;如果有&#xff0c;就将它们备份一下 用yum repolist命令测试&#xff0c;当前系统已经没有可用yum源 输入命令wget -…

Java二十三种设计模式-建造者模式(4/23)

建造者模式&#xff1a;构建复杂对象的专家 引言 建造者模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;用于创建一个复杂的对象&#xff0c;同时允许用户只通过指定复杂对象的类型和内容就能构建它们&#xff0c;它将对象的构建和表示分离&am…

【机器学习】12.十大算法之一支持向量机(SVM - Support Vector Machine)算法原理讲解

【机器学习】12.十大算法之一支持向量机&#xff08;SVM - Support Vector Machine&#xff09;算法原理讲解 一摘要二个人简介三基本概念四支持向量与超平面4.1 超平面&#xff08;Hyperplane&#xff09;4.2 支持向量&#xff08;Support Vectors&#xff09;4.3 核技巧&…

Redis Cluster 工具

脚本 1 slots.sh #!/bin/bash# Connect to Redis Cluster and retrieve node information nodes_info echo "CLUSTER NODES" | rd 10.XX.33.202 6011# Check if redis-cli command executed successfully if [ $? -ne 0 ]; thenecho "Error: Unable to …

【Django+Vue3 线上教育平台项目实战】构建课程详情页与集成视频播放功能

文章目录 前言一、课程列表页面a.后端代码b.前端代码 二、课程详情页面a. 视频播放功能的集成1.获取上传视频的链接地址2.集成在前端页面中1>使用vue-alipayer视频播放组件2>使用video标签 b. 页面主要内容展示1.后端代码1>分析表2>核心逻辑 2.前端代码3.效果图 前…

LLM_入门指南(零基础搭建大模型)

本文主要介绍大模型的prompt&#xff0c;并且给出实战教程。即使零基础也可以实现大模型的搭建。 内容&#xff1a;初级阶段的修炼心法&#xff0c;帮助凝聚和提升内力&#xff0c;为后续修炼打下基础。 1、prompt 1.1含义和作用 prompt就是提示工程的意思。在大型语言模型中…

手撕排序算法:冒泡排序

文章目录 1.算法思想2.冒泡排序具体过程3.算法分析3.1时间复杂度3.2空间复杂度 4.算法的优缺点4.1算法的优点4.2算法的缺点 5.冒泡排序优化方案6.算法实现7.实战7.1 力扣88. 合并两个有序数组7.2力扣2148.元素计数7.3力扣1046.最后一块石头的重量 冒泡排序(Bubble Sort)是一种简…

线程池-拒绝策略

线程池-拒绝策略 RejectedExecutionHandlerAbortPolicyCallerRunsPolicyDiscardPolicyDiscardOldestPolicy自定义拒绝策略 当核心线程已用尽 & 阻塞队列已满 & 超过最大线程数时&#xff0c;再向线程池提交任务&#xff0c;则会触发线程池的拒绝策略。 RejectedExecuti…

微信小程序 2024年更新内容汇总

本心、输入输出、结果 文章目录 微信小程序 2024年更新内容汇总v3.4.10 (2024-07-03)v3.4.9 (2024-06-26)v3.4.8 (2024-06-19)v3.4.7 (2024-06-07)v3.4.6 (2024-05-29)v3.4.5 (2024-05-23)v3.4.4 (2024-05-11)v3.4.3 (2024-04-24)v3.4.2 (2024-04-11)v3.4.1 (2024-04-02)v3.4.1…

Python爬虫与文本到语音转换实战:获取并播报长沙天气

简介&#x1f495; 在本文中&#xff0c;我们将通过一个简单的Python脚本&#xff0c;演示如何使用网络爬虫技术获取长沙的天气信息&#xff0c;并使用文本到语音技术将天气信息播报出来。我们将使用pyttsx3库进行语音播报&#xff0c;使用requests库来发起网络请求&#xff0…

自动驾驶-2D目标检测

yolo及yolo的变体 anchor boxes (锚框) intersection over union 并集交集 用于计算两个边界框的差异程度 bounding box predictions 边界框预测 non maximum suppression非极大值抑制 为了分离这些边界框并为每个对象获得单个边界框&#xff0c;我们使用IOU。这种获取单…

【设计模式之美】【创建型】建造者模式:处理复杂成员变量以及它们之间的关系

文章目录 一. 使用场景二. 具体实现三. 小结1. 结合场景使用2. 与工厂模式的区别 建造者模式本身不难&#xff0c;重点是掌握好它的适用场景。 一. 使用场景 如果一个类中有很多属性&#xff0c;为了避免构造函数的参数列表过长&#xff0c;影响代码的可读性和易用性&#xf…