linux kthread任务管理

目录

  • 一、linux 创建内核线程
    • 1.1 kthread_create
    • 1.2 kthread_create_worker + kthread_queue_work
  • 二、设置线程优先级和调度策略
    • 2.1 sched_setscheduler
    • 2.2 调度策略

一、linux 创建内核线程

1.1 kthread_create

在 linux 中,可以使用 kthread_create 接口创建内核线程,该接口原型如下:

struct task_struct *kthread_create(int (*threadfn)(void *data), void *data, const char namefmt[], ...);

入参含义:

- threadfn:线程函数的入口点。
- data:传递给线程函数的参数。
- namefmt:线程的名字,可以用格式化字符串指定。

示例代码:

#include <linux/kthread.h>
#include <linux/delay.h>// 线程函数
int thread_function(void *data) {while (!kthread_should_stop()) {// 线程的主要工作pr_info("Thread is running\n");ssleep(5); // 休眠5秒}return 0;
}// 在合适的地方创建线程
struct task_struct *task;
task = kthread_create(thread_function, NULL, "my_thread");
if (!IS_ERR(task)) {wake_up_process(task); // 启动线程
}

1.2 kthread_create_worker + kthread_queue_work

kthread_create_worker 主要用于创建一个用于管理工作队列的工作线程。
函数原型:

struct kthread_worker *kthread_create_worker(unsigned int flags, const char namefmt[], ...);

入参含义:

- flags:创建worker时的标志。
- namefmt:worker的名称。

kthread_queue_work 用于将一个工作项添加到由kthread_worker 管理的工作队列中。
函数原型:

void kthread_queue_work(struct kthread_worker *worker, struct kthread_work *work);

入参含义:

-worker:目标worker。
-work:要执行的工作。

示例代码:

#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/slab.h>static struct kthread_worker *worker;
static struct kthread_work work;void work_function(struct kthread_work *work) {pr_info("Work function is running\n");
}int __init my_module_init(void) {worker = kthread_create_worker(0, "my_worker");if (IS_ERR(worker)) {pr_err("Failed to create kthread worker\n");return PTR_ERR(worker);}// 初始化工作kthread_init_work(&work, work_function);// 将工作排队kthread_queue_work(worker, &work);return 0;
}void __exit my_module_exit(void) {kthread_destroy_worker(worker);
}module_init(my_module_init);
module_exit(my_module_exit);

上述示例代码中,

  • kthread_create_worker创建一个工作队列kthread_worker
  • kthread_queue_work 将一个工作项 kthread_work 添加到工作队列 kthread_worker;
  • 每调用一次 kthread_queue_work(worker, &work);,工作项 kthread_work 对应的执行函数 work_function 就会得到一次调用。

二、设置线程优先级和调度策略

2.1 sched_setscheduler

sched_setscheduler 接口是 linux 内核中,设置特定线程或进程优先级和调度策略的接口。函数原型:

int sched_setscheduler(struct task_struct *p, int policy, const struct sched_param *param);

入参说明

- p:指向目标任务(线程或进程)的 task_struct 结构体的指针。
- policy:调度策略。
- param:指向 sched_param 结构体的指针,包含了调度参数,如优先级。

kthread_create_worker + sched_setscheduler 创建线程并设置调度策略和优先级:

static int __init my_module_init(void) {struct sched_param param;int ret;// 创建内核线程工作队列my_worker = kthread_create_worker(0, "my_worker");// 获取内核线程的task_structmy_worker_thread = my_worker->task;// 设置调度策略和优先级param.sched_priority = MAX_RT_PRIO - 1;  // 设置为最高实时优先级ret = sched_setscheduler(my_worker_thread, SCHED_FIFO, &param);return 0;
}

kthread_create + sched_setscheduler 创建线程并设置调度策略和优先级:

// 线程函数
static int thread_function(void *data) {while (!kthread_should_stop()) {}return 0;
}static int __init my_module_init(void) {struct sched_param param;int ret;// 创建内核线程my_thread = kthread_create(thread_function, NULL, "my_thread");// 设置调度策略和优先级param.sched_priority = MAX_RT_PRIO - 1;  // 设置为最高实时优先级ret = sched_setscheduler(my_thread, SCHED_FIFO, &param);// 启动内核线程wake_up_process(my_thread);return 0;
}

2.2 调度策略

  • SCHED_NORMAL:普通调度策略,也称为 SCHED_OTHER。Linux 默认的普通任务调度策略,基于时间片轮转调度算法,适用于大多数用户进程和内核线程。

  • SCHED_FIFO:先进先出调度策略。使用该策略时,系统优先调用高优先级的任务,想通优先级的任务按照先到先服务的顺序执行,只有在队列中所有优先级最高的任务都执行完或者放弃 CPU 后,才会执行其他任务。优先级使用 sched_param 结构中的 sched_priority 成员设置,值越小优先级越高(0 最高)。

  • SCHED_RR:循环调度策略。优先高优先级任务+相同优先级先进先出+每个任务时间片轮转,类似于 SCHED_FIFO,但每个任务有一个时间片,如果任务在该时间片内没有运行完毕,会将任务移到队列末尾等待下一轮调度。也可以通过 sched_param 结构的 sched_priority 设置优先级。

  • SCHED_BATCH:用于低优先级任务的批处理。用于大量计算密集型任务,通常在系统负载较低时,调度器会执行 SCHED_BATCH 线程。

  • SCHED_IDLE:专为低优先级的后台任务设计。只有在没有其他更重要的任务需要执行时,才会考虑执行 SCHED_IDLE 线程。

  • SCHED_DEADLINE:允许任务在预定的截止时间内完成执行,以满足实时系统对任务响应时间的严格要求。deadline 调度策略为每个任务分配固定的 CPU 时间片(Budget),并指定每个周期内允许执行的最大时间量(Period)。

参考:
SCHED_FIFO与SCHED_OTHER调度机制

【Linux 内核】进程管理 - 进程优先级 ② ( prio 调度优先级 | static_prio 静态优先级 | normal_prio 正常优先级 | rt_priority 实时优先级 )

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

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

相关文章

移动校园(7)ii:uniapp路由响应拦截器处理token,以及微信小程序报错当前页面正在处于跳转状态,请稍后再进行跳转....

依据昨天的写完&#xff0c;在token过期之后&#xff0c;再次调用接口&#xff0c;会触发后端拦截&#xff0c;扔进全局错误处理中间件 前端说明提示都没有&#xff0c;只有一个这个&#xff0c;现在优化一下&#xff0c;再写一个类似全局后置守卫&#xff0c;当状态码是401的时…

MySQL——数据连接池

数据库连接 --- 执行完毕 --- 释放&#xff08;连接到释放的过程十分浪费系统资源&#xff09; 池化技术&#xff1a;准备一些预先的资源&#xff0c;过来就连接预先准备好的 编写连接池&#xff0c;实现一个接口 DataSource 开源数据源实现&#xff08;拿来即用&#xff09;…

增强安全防护,解读智慧校园系统的登录日志功能

在构建智慧校园系统时&#xff0c;登录日志功能扮演着不可或缺的角色&#xff0c;它不仅是系统安全的守护者&#xff0c;也是提升管理效率和确保合规性的有力工具。这一机制详细记录每次登录尝试的方方面面&#xff0c;涵盖了时间戳、用户身份、登录来源的IP地址乃至使用的设备…

phpcms 升级php8.3.8

windows 2008 server 不支持php8.3.8,需升级为windows 2012 1.下载php8.3.8 PHP8.3.9 For Windows: Binaries and sources Releases 2.配置php.ini (1.)在php目录下找到php.ini-development文件&#xff0c;把它复制一份&#xff0c;改名为php.ini (2.)修改php安装目录 根…

《昇思 25 天学习打卡营第 10 天 | ResNet50 迁移学习 》

《昇思 25 天学习打卡营第 10 天 | ResNet50 迁移学习 》 活动地址&#xff1a;https://xihe.mindspore.cn/events/mindspore-training-camp 签名&#xff1a;Sam9029 使用迁移学习进行狼狗图像分类 简介 在机器学习和深度学习中&#xff0c;我们经常面临数据不足的问题。 迁…

python【文件操作】

文件操作 一、创建文件夹二、文件操作模式1.覆盖写入2.读取3.追加 三、 Python脚本在文件中查找和替换文本四、 python清空文件夹 一、创建文件夹 判断文件或者文件夹是否存在 import ospathrD://测试文件夹 if not os.path.exists(path):os.mkdir(path)print(os.path.exists…

C++模板元编程(二)——完美转发

完美转发指的是函数模板可以将自己的参数“完美”地转发给内部调用的其它函数。所谓完美&#xff0c;即不仅能准确地转发参数的值&#xff0c;还能保证被转发参数的左、右值属性不变。 文章目录 场景旧的方法新的方法内部实现参考文献 场景 思考下面的代码&#xff1a; templ…

高防服务器的重要性

在数字化时代&#xff0c;网络安全已成为企业和个人最为关注的问题之一。随着网络攻击的日益频繁和复杂&#xff0c;传统的服务器租用服务已难以满足高安全需求的市场。高防服务器租用应运而生&#xff0c;成为保护网络安全的重要解决方案。本文将探讨高防服务器租用的概念、重…

专业140+总分420+天津大学815信号与系统考研经验天大电子信息与通信工程,真题,大纲,参考书。

顺利上岸天津大学&#xff0c;专业课815信号与系统140&#xff0c;总分420&#xff0c;总结一些自己的复习经历&#xff0c;希望对于报考天大的同学有些许帮助&#xff0c;少走弯路&#xff0c;顺利上岸。专业课&#xff1a; 815信号与系统&#xff1a;指定教材吴大正&#xf…

2-26 基于matlab开发的制冷循环模型

基于matlab开发的制冷循环模型。Simscape两相流域中的制冷循环模型&#xff0c;在simulink中完成多循环温度控制。程序已调通&#xff0c;可直接运行。 2-26 制冷循环模型 Simscape两相流域 - 小红书 (xiaohongshu.com)

Arduino ESP8266 开发环境搭建

Arduino ESP8266 开发环境搭建 很久之前学嵌入式时&#xff0c;用过Arduino8266进行开发&#xff0c;开发成本低、难度小&#xff0c;体验很不错。 近期&#xff0c;又突然要用&#xff0c;遂再次搭建环境&#xff0c;但变动挺多&#xff0c;有些小波折&#xff0c;开贴记录。…

生成式AI应用实列和价值链

生成式AI应用实列和价值链 生成式AI应用实列ChatGPTGeminiGitHub CopilotSynthesia 价值链 生成式AI应用实列 ChatGPT ChatGPT 并不是生成式 AI 行业中唯一的公司。 Stability AI 的 Stable Diffusion 可以根据文本描述生成图像&#xff0c;发布后 90 天内&#xff0c;在 Git…

vue是如何进行监听数据变化的?vue2和vue3分别是什么,vue3为什么要更换

在 Vue 中&#xff0c;数据变化的监听是通过响应式系统来实现的。Vue 2.x 和 Vue 3 在这方面有一些区别。 Vue 2.x 的数据监听 Vue 2.x 使用的是 Object.defineProperty() 方法来实现数据的响应式。当你声明一个 Vue 实例的数据对象时&#xff0c;Vue 将遍历这个对象的属性&a…

清除屏幕上信息的命令clear

清除屏幕上信息的命令clear There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about being cheated should leave quickly. 清…

高考志愿填报千万要注意这四点

在高考志愿填报过程中&#xff0c;确实有很多需要留心的点。我为你总结了四个关键点&#xff0c;希望能帮助你顺利完成志愿填报&#xff1a; 1、学校提供的支持 学校作为学生志愿填报咨询服务的主阵地&#xff0c;应提供体系化和制度化的支持。包括及时关注并传达政策动向和相…

行内元素、块级元素居中

行内元素居中 水平居中 {text-align&#xff1a;center;}垂直居中 单行——行高等于盒子高度 <head><style>.father {width: 400px;height: 200px;/* 行高等于盒子高度&#xff1a;line-height: 200px; */line-height: 200px;background-color: pink;}.son {}&…

如何做好IT类的技术面试?

我们在找工作时&#xff0c;需要结合自己的现状&#xff0c;针对意向企业做好充分准备。作为程序员&#xff0c;你有哪些面试IT技术岗的技巧&#xff1f; 方向一&#xff1a;分享你面试IT公司的小技巧 我分享一些基于广泛观察和用户反馈的面试IT公司的小技巧&#xff1a; 技术准…

孟德尔随机化-痛风

写在前面 昨天看到文献&#xff0c;称饮酒与痛风无关联&#xff0c;甚是疑惑&#xff0c;今天刚好看了一篇新文献&#xff0c;虽然不是主要讲饮酒与痛风的&#xff0c;但也有牵扯到这方面内容&#xff0c;而且是相反的内容&#xff0c;特记录一下。 孟德尔随机化-受教育程度与…

vuepress创建步骤

背景 记录vuepress配置步骤&#xff0c;以便下次使用快速上手。 读此文章之前默认您已经学会了创建vuepress项目。vuepres快速开始 最终成品 doc.jeecgflow.com 配置步骤 创建.vuepress 目录。 你的文档目录下创建一个 .vuepress 目录。 创建.vuepress/config.js module.e…

mysql面试题 Day4

1 什么是覆盖索引&#xff1f;对要查询的列 和 查询条件中的列 有什么要求 覆盖索引&#xff08;Covering Index&#xff09;是指一个索引包含了一次查询所需的全部列&#xff0c;因此可以完全满足查询需求&#xff0c;而无需访问实际的表行数据。&#xff08;即避免回表操作&…