13 内核开发-任务调度-Work queues工作队列

13 内核开发-任务调度-Work queues工作队列

目录

13 内核开发-任务调度-Work queues工作队列

1.定义

2.内涵

3.使用示例

4.具体代码使用实践

5.注意事项

6.最佳实践

7.总结

9.比较 workqueue_struct 与 tasklet



课程简介
Linux内核开发入门是一门旨在帮助学习者从最基本的知识开始学习Linux内核开发的入门课程。该课程旨在为对Linux内核开发感兴趣的初学者提供一个扎实的基础,让他们能够理解和参与到Linux内核的开发过程中。

课程特点:
1. 入门级别:该课程专注于为初学者提供Linux内核开发的入门知识。无论你是否具有编程或操作系统的背景,该课程都将从最基本的概念和技术开始,逐步引导学习者深入了解Linux内核开发的核心原理。

2. 系统化学习:课程内容经过系统化的安排,涵盖了Linux内核的基础知识、内核模块编程、设备驱动程序开发等关键主题。学习者将逐步了解Linux内核的结构、功能和工作原理,并学习如何编写和调试内核模块和设备驱动程序。

3. 实践导向:该课程强调实践,通过丰富的实例和编程练习,帮助学习者将理论知识应用到实际的Linux内核开发中。学习者将有机会编写简单的内核模块和设备驱动程序,并通过实际的测试和调试来加深对Linux内核开发的理解。

4. 配套资源:为了帮助学习者更好地掌握课程内容,该课程提供了丰富的配套资源,包括教学文档、示例代码、实验指导和参考资料等。学习者可以根据自己的学习进度和需求,灵活地利用这些资源进行学习和实践。

无论你是计算机科学专业的学生、软件工程师还是对Linux内核开发感兴趣的爱好者,Linux内核开发入门课程都将为你提供一个扎实的学习平台,帮助你掌握Linux内核开发的基础知识,为进一步深入研究和应用Linux内核打下坚实的基础。

这一讲,主要分享如何在内核开模块开发中如何使用工作对了 workqueue。


1.定义


内核中调度任务除了tasklet 可以调度任务外,还可以使用 workqueue ,内核里面使用 CFS 执行队列里面的任务,所以熟悉workqueue 就要先了解 CFS 。

Completely Fair Scheduler (CFS) 
完全公平调度程序 (CFS) 是 Linux 内核中的一种进程调度程序,它旨在为交互式应用程序提供公平且可预测的性能。它于 2007 年引入内核,并逐渐成为 Linux 系统中最常用的调度程序。

2.内涵


CFS 的主要目标是:

  1. 公平性: 确保所有进程获得公平的 CPU 时间片。
  2. 可预测性: 进程应该能够预测它们何时将获得 CPU 时间。
  3. 交互性: 交互式应用程序(例如桌面环境和游戏)应该获得优先级,以提供流畅的性能。

CFS 通过使用以下机制来实现这些目标:

  1. 虚拟运行时间 (vruntime): 每个进程都有一个 vruntime 值,它表示进程在没有被抢占的情况下运行的时间。
  2. 公平时间片: 每个进程在运行一段时间后都会被抢占,这个时间段称为公平时间片。公平时间片的大小是根据进程的优先级动态计算的。
  3. 赤字会计: 当一个进程被抢占时,它会累积赤字。赤字表示进程在被抢占之前应该运行的额外时间。
  4. 负载平衡: CFS 尝试将进程均匀地分布在所有可用的 CPU 上,以最大限度地提高系统吞吐量。


CFS 的工作原理

  1. CFS 为每个进程维护一个 vruntime 值。
  2. CFS 根据进程的优先级计算公平时间片。
  3. CFS 允许进程运行其公平时间片。
  4. 如果一个进程在公平时间片结束之前被抢占,则它的赤字会增加。
  5. 当一个进程的赤字足够大时,CFS 会提升它的优先级,以便它可以更快地运行。
  6. CFS 尝试将进程均匀地分布在所有可用的 CPU 上。
  7. CFS 是一种非常有效的调度程序,它可以为交互式应用程序提供公平且可预测的性能。它也是一个非常可配置的调度程序,可以根据系统的特定需求进行调整。

此外,CFS 是一个层次结构调度程序,这意味着它使用多个队列来管理进程。CFS 使用红黑树来跟踪进程的 vruntime 值。CFS 可以与其他调度程序(例如实时调度程序)结合使用。


3.使用示例

(a) stuct workqueue_struct *myqueue;

workqueue_struct 是内核中用于表示工作队列的数据结构。工作队列是一种机制,允许内核将任务委托给内核线程池异步执行。

(b)alloc_workqueue("my_workqueue", WQ_HIGHPRI, 0);

alloc_workqueue() 函数用于分配和初始化一个新的工作队列。它需要以下参数:

*const char name: 工作队列的名称。
int flags: 工作队列的标志。可以使用的标志包括:
WQ_HIGHPRI:创建一个高优先级工作队列。
WQ_UNBOUND:创建一个不绑定到任何特定 CPU 的工作队列。
WQ_SYSFS:创建一个在 sysfs 中可见的工作队列。
alloc_workqueue() 函数成功时返回一个 workqueue_struct 指针,失败时返回 NULL。

(c)destroy_workqueue(my_workqueue);

destroy_workqueue() 函数用于销毁一个工作队列。它需要一个 workqueue_struct 指针作为参数。

destroy_workqueue() 函数成功时返回 0,失败时返回 -1。


4.具体代码使用实践
#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/workqueue.h> static struct workqueue_struct *queue = NULL; 
static struct work_struct work; static void work_handler(struct work_struct *data) 
{ pr_info("work handler function.\n"); 
} static int __init sched_init(void) 
{ queue = alloc_workqueue("HELLOWORLD", WQ_UNBOUND, 1); INIT_WORK(&work, work_handler); queue_work(queue, &work); return 0; 
} static void __exit sched_exit(void) 
{ destroy_workqueue(queue); 
} module_init(sched_init); 
module_exit(sched_exit); MODULE_LICENSE("GPL"); 
MODULE_DESCRIPTION("Workqueue example");
5.注意事项


在内核中使用 workqueue_struct 时需要注意以下几点:

  1.     选择正确的标志: 在调用 alloc_workqueue() 函数时,必须仔细选择要使用的标志。不同的标志会影响工作队列的行为方式。例如,WQ_HIGHPRI 标志会创建一个高优先级工作队列,而 WQ_UNBOUND 标志会创建一个不绑定到任何特定 CPU 的工作队列。
  2.     正确使用工作队列: 必须正确使用工作队列。例如,不应在中断上下文中使用工作队列。
  3.     释放工作队列: 在使用完工作队列后,必须使用 destroy_workqueue() 函数释放它。

使用 workqueue_struct 更多具体事项:

  1.     避免死锁: 如果工作队列中的任务试图获取已经在持有该锁的内核对象上的锁,则可能会发生死锁。
  2.     避免饥饿: 如果工作队列中的任务具有非常高的优先级,则可能会饿死其他优先级较低的任务。
  3.     性能注意事项: 工作队列可能会对内核性能产生影响。例如,如果工作队列中的任务非常耗时,则可能会导致内核性能下降。

6.最佳实践


在内核中使用 workqueue_struct 的最佳实践包括:

  1. 选择正确的标志: 在调用 alloc_workqueue() 函数时,请仔细选择要使用的标志。不同的标志会影响工作队列的行为方式。例如,WQ_HIGHPRI 标志会创建一个高优先级工作队列,而 WQ_UNBOUND 标志会创建一个不绑定到任何特定 CPU 的工作队列。一般来说,应避免使用 WQ_HIGHPRI 标志,除非绝对必要。
  2. 正确使用工作队列: 必须正确使用工作队列。例如,不应在中断上下文中使用工作队列。此外,应避免在工作队列中执行耗时的任务。
  3. 释放工作队列: 在使用完工作队列后,必须使用 destroy_workqueue() 函数释放它。
  4. 避免死锁: 如果工作队列中的任务试图获取已经在持有该锁的内核对象上的锁,则可能会发生死锁。为了避免死锁,应注意不要在工作队列中获取内核对象的锁。
  5. 避免饥饿: 如果工作队列中的任务具有非常高的优先级,则可能会饿死其他优先级较低的任务。为了避免饥饿,应避免在工作队列中创建具有非常高优先级的任务。
  6. 性能注意事项: 工作队列可能会对内核性能产生影响。例如,如果工作队列中的任务非常耗时,则可能会导致内核性能下降。为了避免性能问题,应避免在工作队列中执行耗时的任务。
  7. 使用工作队列来执行异步任务: 工作队列最适合用于执行异步任务。例如,工作队列可用于将任务委托给内核线程池以在后台执行。
  8. 使用工作队列来提高可伸缩性: 工作队列可以提高内核的可伸缩性,因为它们允许内核在多个 CPU 上并行执行任务。
  9. 使用工作队列来提高模块性: 工作队列可以提高内核的模块性,因为它们允许内核以模块化方式安排任务。

7.总结

总的来说,与 tasklet 相比,在内核中使用 CFS workqueue_struct 的主要优点是更好的可伸缩性、更少的上下文切换开销、更好的模块性和更少的同步开销。


tasklet 在某些情况下仍然比 workqueue_struct 更合适。例如,tasklet 更适合处理需要非常快速响应时间的任务。workqueue_struct 更适合处理需要高吞吐量或低延迟的任务,而 tasklet 更适合处理需要非常快速响应时间的任务。


9.比较 workqueue_struct 与 tasklet
任务调度优点缺点
workqueue_struct

更好的可伸缩性: workqueue_struct 可以跨多个 CPU 并行执行任务,而 tasklet 只能在单个 CPU 上执行。这使得 workqueue_struct 更适合处理需要高吞吐量或低延迟的任务。


更少的上下文切换开销: workqueue_struct 使用内核线程池来执行任务,而 tasklet 则使用 softirq。内核线程池的上下文切换开销通常低于 softirq。


更好的模块性: workqueue_struct 可以更轻松地与其他内核子系统集成。例如,workqueue_struct 可以与内核事件通知机制一起使用,允许在事件发生时安排任务。


更少的同步开销: workqueue_struct 使用无锁数据结构来管理任务队列,而 tasklet 则使用自旋锁。这使得 workqueue_struct 在高并发情况下具有更好的可扩展性。

延迟可能更高: workqueue_struct 中的任务可能需要比 tasklet 更长的时间才能执行,因为它们必须排队等待内核线程池中的线程可用。


可能更难调试: workqueue_struct 中的任务在内核线程池中执行,这可能使调试更困难。

tasklet

非常低的延迟: tasklet 在中断上下文中执行,这意味着它们可以非常快速地响应事件。


更简单的调试: tasklet 在中断上下文中执行,这可以使调试更简单。

可伸缩性较差: tasklet 只能在单个 CPU 上执行,这意味着它们不适合处理需要高吞吐量或低延迟的任务。


更多的上下文切换开销: tasklet 使用 softirq 来执行任务,而 softirq 的上下文切换开销通常高于内核线程池。


模块性较差: tasklet 难以与其他内核子系统集成。
更多的同步开销: tasklet 使用自旋锁来管理任务队列,这可能导致高并发情况下出现性能问题。

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

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

相关文章

ENVI不同版本个人使用对比

ENVI不同版本个人使用对比 文章目录 ENVI不同版本个人使用对比前言对比5.3学习版5.6学习版6.0试用版 总结 前言 目前来看&#xff0c;流传较广的可供大家免费获取的ENVI版本主要是5.3学习版 5.6学习版 6.0学习版这三个版本&#xff0c;不同的版本有不同特色&#xff0c;在此做…

关于面向对象与面向过程的基本概念

什么是面向对象与面向过程编程 面向对象编程&#xff08;OOP&#xff09;和面向过程编程&#xff08;POP&#xff09;是两种主要的编程范式&#xff0c;它们在解决问题的方法和组织代码的方式上有所不同。C#和Java都是支持这两种编程范式的语言&#xff0c;但它们在实现细节上…

C#基础|StringBuilder字符串如何高效处理。

哈喽&#xff0c;你好&#xff0c;我是雷工。 字符串处理在C#程序开发中是使用频率比较高的&#xff0c;但常规的字符串处理方式对内存占用比较多&#xff0c;为了优化内存&#xff0c;减少不必要的内存浪费&#xff0c;引入了StringBuilder类。 下面学习下StringBuilder类的使…

PC-3000 Flash:NAND 闪存设备(包括一体式U盘)数据恢复的重量级工具(一)

天津鸿萌科贸发展有限公司从事数据安全业务20余年&#xff0c;在数据恢复、数据取证、数据备份等领域有丰富的案例经验、前沿专业技术及良好的行业口碑。同时&#xff0c;公司面向取证机构及数据恢复公司&#xff0c;提供数据恢复实验室建设方案&#xff0c;包含 PC-3000 系列数…

LeetCode 热题 100 Day05

矩阵相关题型 Leetcode 73. 矩阵置零【中等】 题意理解&#xff1a; 将矩阵中0所在位置&#xff0c;行|列置换为全0 其中可以通过记录0元素所在的行、列号&#xff0c;来标记要置换的行|列 将对应位置置换为0 解题思路&#xff1a; 第一个思路&#xff1a; 可以…

React | classnames

classnames 这个库在我们的项目中有大量的使用到&#xff0c;它不仅很实用&#xff0c;还非常好用&#xff0c;但还有人不知道这个库&#xff0c;我真的是十分心痛。 通过 classnames&#xff0c;我们可以给组件设置多个 className&#xff0c;还可以根据需要动态设置 classNa…

模块四:前缀和——DP35 【模板】二维前缀和

文章目录 题目描述算法原理解法一&#xff1a;暴力模拟&#xff08;时间复杂度为O(n*m*q)&#xff09;解法二&#xff1a;二维前缀和&#xff08;时间复杂度为O(m*n)O(q)) 代码实现解法二&#xff1a;前缀和&#xff08;C)Java 题目描述 题目链接&#xff1a;DP35 【模板】二维…

三星电脑文件夹误删了怎么办?恢复方案在此

在使用三星电脑的过程中&#xff0c;我们可能会不小心删除了某个重要的文件夹&#xff0c;其中可能包含了工作文件、家庭照片、视频或其他珍贵的数据。面对这种突发情况&#xff0c;不必过于焦虑。本文将为您提供几种有效的恢复方案&#xff0c;希望能帮助您找回误删的文件夹及…

openEuler-22.03安装 mysql8.0.32

一、下载解压 下载地址&#xff1a; MySQL :: Download MySQL Community Server (Archived Versions) tar -xvf mysql-8.0.32-1.el7.x86_64.rpm-bundle.tar -C /opt/mysql-8.0.32 二、安装 最开始安装一直报错 缺少 libcrypto.so.10库文件,安装openssl可以解决 wget http://…

kafka 线上消费积压问题

背景 线上kafka 流量大&#xff0c;消费小于生产&#xff0c;如何处理&#xff1f; 方案 增加consumer数量 可以增加consumer的消费者&#xff0c;不过这个只能在一定程序上缓解&#xff0c;如果consumer 数量超过partition 数&#xff0c;那有的就会空转&#xff0c;解决不…

rabbitmq报错

文章目录 Applying plugin configuration to rabbitDESKTOP-C3HQ9BK... Plugin configuration unchanged.rabbitmq-service.bat start和rabbitmq-plugins enable rabbitmq_management这两个命令在RabbitMQ中具有不同的功能和用途。以下是两者之间的主要区别&#xff1a; Applyi…

国家开放大学2024春学期《社会调查研究与方法-邮政学院》形成性考核一参考答案

答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 某市城区有 18 个社区&#xff0c;常住居民 10000 户&a…

Java客户端如何直接调用es的API

Java客户端如何直接调用es的API 一. 问题二. withJson 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 一. 问题 今天做项目的时候&#xff0c;想要直接通过java客户端调用es的api…

揭秘工业大模型:从人工智能小白到技术先锋

工业大模型的五个基本问题 信息化时代&#xff0c;数字化转型成为企业提升营运效率、应对经营风险和提升核心竞争力的重要途径。在此过程中&#xff0c;数据作为一种客观存在的资源&#xff0c;所产生的价值日益凸显。党的十九届四中全会从国家治理体系和治理能力现代化的高度将…

【万字长文】看完这篇yolov4详解,那算是真会了

前言 目标检测作为计算机视觉领域的一个核心任务&#xff0c;其目的是识别出图像中所有感兴趣的目标&#xff0c;并给出它们的类别和位置。YOLO&#xff08;You Only Look Once&#xff09;系列模型因其检测速度快、性能优异而成为该领域的明星。随着YOLOv4的推出&#xff0c;…

Java基础知识总结(78)

/** * 线程加锁 */ public class SynchronizedDemo2 { //静态成员变量 在主内存中 static int i; //静态成员方法 public static void add(){ synchronized (SynchronizedDemo2.class){ i; } } public static void main(String[] args) throws InterruptedException { Thread t…

双塔模型在召回和粗排的区别

答案参考&#xff1a;推荐系统中&#xff0c;双塔模型用于粗排和用于召回的区别有哪些? - 知乎 召回和粗排在不同阶段面临样本不一样&#xff0c;对双塔来说样本分布差异会使召回和粗排采取不一样的方式。召回打分空间是全部item空间&#xff0c;曝光只有很少一部分&#xff0…

【机器学习】集成学习---Bagging之随机森林(RF)

【机器学习】集成学习---Bagging之随机森林&#xff08;RF&#xff09; 一、引言1. 简要介绍集成学习的概念及其在机器学习领域的重要性。2. 引出随机森林作为Bagging算法的一个典型应用。 二、随机森林原理1. Bagging算法的基本思想2. 随机森林的构造3. 随机森林的工作机制 三…

ClickHouse 如何实现数据一致性

文章目录 ReplacingMegreTree 引擎数据一致性实现方式1.ReplacingMegreTree 引擎2.ReplacingMegreTree 引擎 手动合并3.ReplacingMegreTree 引擎 FINAL 查询4.ReplacingMegreTree 引擎 标记 GroupBy5.允许偏差 前言&#xff1a;在大数据中&#xff0c;基本上所有组件都要求…

Docker创建镜像之--------------基于Dockerfile创建

目录 一、在编写 Dockerfile 时&#xff0c;有严格的格式需要遵循 二、Dockerfile 操作常用的指令 2.1ENTRYPOINT和CMD共存的情形 2.2ENTRYPOINT和CMD的区别 2.3ADD 与COPY的区别 三、Dockerfile案例 3.1构建apache镜像 3.1.1 创建镜像目录方便管理 3.1.2创建编写dock…