Linux内核线程编程方法

Linux内核线程发生死锁或死循环后如何触发系统宕机重启 在Linux内核中,线程死锁或死循环是一种严重的问题,可能会导致系统无响应或无法继续正常运行。在某些情况下,为了恢复系统的正常运行,我们可能需要触发系统宕机并进行重启。本文将介绍如何在发生线程死锁或死循环时通过编程触发系统宕机重启。函数时,内核会进入宕机状态并记录宕机信息,然后重启系统。为了演示该过程,我们将创建一个简单的内核模块,其中包含一个线程死循环,在死循环中调用。请注意,触发系统宕机是一项危险操作,应该谨慎使用。上述代码中,我们定义了一个内核模块,其中包含一个线程函数。,在该函数中执行一个死循环。 阅读详情

写的不错,多说也无益,看看前人的经验。

一点备注:内核线程实际上是内核进程,只是大家的地址空间是内核空间,所以内核线程间的切换没有真正意义上的地址空间切换。具体看看,他的一些编程方法,退出机制和windows多线程编程需要注意的事项差不多。

===========================================================================================================

Linux内核线程编程方法

 

内核经常需要在后台执行一些操作,这种任务就可以通过内核线程(kernle thread)完成--独立运行在内核空间的标准进程。内核线程和普通的进程间的区别在于内核线程没有独立的地址空间,mm指针被设置为NULL;它只在 内核空间运行,从来不切换到用户空间去;并且和普通进程一样,可以被调度,也可以被抢占。实际上,内核线程只能由其他内核线程创建,在现有的内核线程中创建一个新的内核线程的方法:

kthread_create:创建线程。
struct task_struct *kthread_create(int (*threadfn)(void *data),void *data,const char *namefmt, ...);
线程创建后,不会马上运行,而是需要将kthread_create() 返回的task_struct指针传给wake_up_process(),然后通过此函数运行线程。
kthread_run :创建并启动线程的函数:
struct task_struct *kthread_run(int (*threadfn)(void *data),void *data,const char *namefmt, ...);
kthread_stop:通过发送信号给线程,使之退出。
int kthread_stop(struct task_struct *thread);
线程一旦启动起来后,会一直运行,除非该线程主动调用do_exit函数,或者其他的进程调用kthread_stop函数,结束线程的运行。
但如果线程函数正在处理一个非常重要的任务,它不会被中断的。当然如果线程函数永远不返回并且不检查信号,它将永远都不会停止。

1.       头文件

#include <linux/sched.h>   //wake_up_process()

#include <linux/kthread.h> //kthread_create()、kthread_run()

#include <err.h> //IS_ERR()、PTR_ERR()

2.       实现

2.1创建线程

kernel thread可以用kernel_thread创建,但是在执行函数里面必须用daemonize释放资源并挂到init下,还需要用completion等待这一过程的完成。为了简化操作kthread_create闪亮登场。

在模块初始化时,可以进行线程的创建。使用下面的函数和宏定义:

struct task_struct *kthread_create(int (*threadfn)(void *data),

                            void *data,

                            const char namefmt[], ...);

kthread_create源码详解见http://blog.sina.com.cn/s/blog_6237dcca0100gq67.html


#define kthread_run(threadfn, data, namefmt, ...)                     /

({                                                            /

    struct task_struct *__k                                        /

           = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); /

    if (!IS_ERR(__k))                                        /

           wake_up_process(__k);                                /

    __k;                                                     /

})

例如:

static struct task_struct *test_task;

static int test_init_module(void)

{

    int err;

    test_task = kthread_create(test_thread, NULL, "test_task");

    if(IS_ERR(test_task)){

      printk("Unable to start kernel thread./n");

      err = PTR_ERR(test_task);

      test_task = NULL;

      return err;

    }

    wake_up_process(test_task);

    return 0;

}

        module_init(test_init_module);

2.2线程函数

在线程函数里,完成所需的业务逻辑工作。主要框架如下所示:

int threadfunc(void *data){

        …

        while(1){

               set_current_state(TASK_UNINTERRUPTIBLE);

               if(kthread_should_stop()) break;

               if(){//条件为真

                      //进行业务处理

               }

               else{//条件为假

                      //让出CPU运行其他线程,并在指定的时间内重新被调度

                      schedule_timeout(HZ);

               }

        }

        …

        return 0;

}

2.3结束线程

在模块卸载时,可以结束线程的运行。使用下面的函数:

int kthread_stop(struct task_struct *k);

例如:

              static void test_cleanup_module(void)

{

            if(test_task){

                kthread_stop(test_task);

                test_task = NULL;

            }

}

module_exit(test_cleanup_module);

3.       注意事项

(1)       在调用kthread_stop函数时,线程函数不能已经运行结束。否则,kthread_stop函数会一直进行等待。

(2)       线程函数必须能让出CPU,以便能运行其他线程。同时线程函数也必须能重新被调度运行。在例子程序中,这是通过schedule_timeout()函数完成的。

4.性能测试

可以使用top命令来查看线程(包括内核线程)的CPU利用率。命令如下:

       top –p 线程号

可以使用下面命令来查找线程号:

       ps aux|grep 线程名

       注:线程名由kthread_create函数的第三个参数指定。


代码:
 #include <linux/kthread.h>
#include <linux/module.h>
#ifndef SLEEP_MILLI_SEC
#define SLEEP_MILLI_SEC(nMilliSec)/
do { /
long timeout = (nMilliSec) * HZ / 1000; /
while(timeout > 0) /
{ /
timeout = schedule_timeout(timeout); /
} /
}while(0);
#endif
static struct task_struct * MyThread = NULL;
static int MyPrintk(void *data)
{
char *mydata = kmalloc(strlen(data)+1,GFP_KERNEL);
memset(mydata,'/0',strlen(data)+1);
strncpy(mydata,data,strlen(data));
while(!kthread_should_stop())
{
SLEEP_MILLI_SEC(1000);
printk("%s/n",mydata);
}
kfree(mydata);
return 0;
}
static int __init init_kthread(void)
{
MyThread = kthread_run(MyPrintk,"hello world","mythread");
return 0;
}
static void __exit exit_kthread(void)
{
if(MyThread)
{
printk("stop MyThread/n");
kthread_stop(MyThread);
}
}
module_init(init_kthread);
module_exit(exit_kthread);
MODULE_AUTHOR("YaoGang");
这个内核线程的作用就是每隔一秒打印一个“hello world”。
值得一提的是kthread_should_stop函数,我们需要在开启的线程中嵌入该函数并检查此函数的返回值,否则kthread_stop是不起作用的......

WorkBuddy实战技巧:搭建高效AI工作台与自动化流程 在数字化办公场景中,AI工作台正逐渐成为提升个人与团队效率的关键工具。它不同于简单的聊天机器人,而是通过集成技能包(Skill)、自动化触发与文档处理能力,把重复性任务如信息提取、周报生成、数据表格整理等变为标准化流程。其核心原理在于将用户需求拆解为可执行的指令链,并借助本地脚本、API调用及定时任务实现“对话即操作”的智能协作。这种技术价值不仅适用于程序员,更惠及运营、客服、行政、科研等日常与文字数据打交道的群体。从自动签到、会议纪要,到批量处理Excel与合同要点提取,AI工作台的应用场景已覆盖多个高频 阅读详情

相关推荐

足球大数据分析入门:从赔率到预测的完整流程(附数据集)

本文提供了一份足球大数据分析的完整实战指南,涵盖从数据采集、清洗、特征工程到模型构建与评估的全流程。文章详细介绍了如何利用公开数据集与API获取数据,并通过逻辑回归、随机森林等模型进行比赛结果预测,最后强调了模型评估与策略回测的重要性,帮助读者构建自己的分析框架。

r7s8t的博客 404

一文搞懂Linux内核之内核线程

Linux内核可以看作服务进程(管理软硬件资源,响应用户进程的各种进程)。内核需要多个执行流并行,为了防止可能的阻塞,支持多线程。内核线程就是内核的一个分身,可以用以处理一件特定事情,内核线程的调度由内核负责,一个内核线程的处于阻塞状态时不影响其他的内核线程。内核线程是直接由内核本身启动的进程。内核线程实际上是将内核函数委托给独立的进程执行,它与内核中的其他“进程”并行执行。内核线程经常被称之为内核守护进程。周期性地将修改的内存页与页来源块设备同步如果内存页很少使用,则写入交换区。

m0_74282605的博客 3090

Materials - UE5中的PivotPainter

可以使用3DS Max Script中的脚本(Pivot Painter)对模型进行处理,让每个Element都有自己的Pivot Point,来方便控制和制作一些特殊的顶点动画效果;

GT的虚幻引擎文档 1288

Linux: 内核线程简析

linux, 内核线程

JiMoKuangXiangQu的专栏 1294

告别Colmap!在ROS2 Humble上,用Fast-LIVO2直接为3D Gaussian Splatting准备数据全流程

本文详细介绍了在ROS2 Humble环境下,使用Fast-LIVO2为3D Gaussian Splatting(3DGS)准备数据的全流程。通过优化Fast-LIVO2配置、实时数据同步机制和3DGS训练参数,显著提升了三维重建效率和质量,相比传统Colmap流程节省95%以上的预处理时间。适用于Ubuntu22.04系统,适合机器人及自动驾驶领域的三维重建应用。

weixin_28688385的博客 588

Trae+Playwright MCP自动化测试全流程指南:从环境搭建到智能体运行

本文提供了一份详细的Trae与Playwright MCP集成指南,涵盖从Node.js、Python环境搭建到智能体创建的全流程。通过结合MCP协议,AI智能体能够理解任务并驱动Playwright执行复杂的浏览器自动化操作,实现从网页数据抓取到端到端测试的智能工作流。

banana的博客 531

Linux内核线程

在内核模块开发中,也存在线程的概念。和应用程序的线程类似,内核也需要多个线程同时并行地执行,避免可能的阻塞。一旦一个内核线程阻塞,不影响其他进程的工作。所谓“内核线程”,是直接由内核本身启动的进程(内核线程的本质是进程),运行在内核态,它与其他进程”并行”执行。

ych4444的博客 2618

通过一个具体的例子,讲解 SAP Cloud Platform Integration(CPI) 的使用方法

最近笔者由于项目需要,又得学习一个新工具:SAP Cloud Platform Integration,简称 CPI,以前又叫做HCI - HANA Cloud Platform Integration Service.笔者想通过本文,把使用这个工具的第一手体会,分享给曾经用过SAP CRM中间件,但尚未有机会接触到CPI的朋友们。之所以本文标题里把SAP CRM中间件和SAP CPI关联在一起,是因为二者同广义上说,扮演的都是系统集成里中间件的角色。SAP ERP和CRM通过qRFC进行业务数据同步,而中

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2275

linux 内核线程

linux 内核线程

一叶知秋的博客 718

OpenCASCADE:Direct3D CSharp 示例

OpenCASCADE:Direct3D CSharp 示例OpenCASCADE:Direct3D CSharp 示例 OpenCASCADE:Direct3D CSharp 示例 此示例演示了如何在使用CSharp和Windows Presentation Foundation (WPF)编写的.Net应用程序中使用 OCCT 和 DirectX 库。 .Net、OCCT (C++) 和 DirectX 级别之间的连接由用 C++/CLI 编写的代理库OCCProxy和D3DProxy提供。代理库OCC

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1824

uniapp:在map地图组件上添加控件,在地图上添加浮层展示自定义按钮或元素,uniApp如何在Map组件地图上添加悬浮在上面的图标/图片(全平台兼容安卓苹果app、H5网页、微信小程序、nvue)

uni-app的map添加控件问题,uniapp实现地图展示控件,uniapp小程序如何在map组件上增加按钮,uni-app,h5移动端网页,微信小程序,支付宝小程序,Android安卓,苹果ios,app,nvue,Uniapp腾讯地图添加控件,uniapp百度地图添加控件,地图上展示控件并可以点击,在地图上展示控件信息,uniapp map地图怎么向地图上增加工具栏,使用cover-view将控件在地图上展示,解决uniapp map上添加浮层无法显示问题,不显示怎么办,css样式不生效,地图等最高层

✅ 精选推荐文章 3230

【Linux】线程详解

在一个程序里的一个执行路线就叫做线程。更准确的定义是:线程是“一个进程内部的控制序列”一切进程都至少有一个执行线程线程在进程内部运行,本质是在进程地址空间内运行在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更轻量化透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流进程的创建伴随着进程控制块,进程地址空间以及页表的创建,虚拟地址和物理地址就是通过页表建立映射的。

m0_72940975的博客 3686

Python + Playwright:集成 Applitools 进行视觉回归测试(快速入门)

Applitools是一款基于人工智能的视觉验证测试工具,专门用于自动化和验证应用程序的用户界面(UI);Applitools使用视觉回归测试来检测应用程序界面的变化,确保 UI 在不同版本之间的一致性;Applitools的核心功能是通过视觉比较,检测 UI 元素的差异,而无需手动编写复杂的界面检查代码;通过集成Applitools,测试人员可以轻松捕捉和验证界面中的视觉差异,无论是在Web移动端或桌面应用的测试环境;

blues_C的博客 2921

Linux内核线程编程方法(经典)

<br /><br />Linux内核线程编程方法<br /> <br />内核经常需要在后台执行一些操作,这种任务就可以通过内核线程(kernle thread)完成--独立运行在内核空间的标准进程。内核线程和普通的进程间的区别在于内核线程没有独立的地址空间,mm指针被设置为NULL;它只在 内核空间运行,从来不切换到用户空间去;并且和普通进程一样,可以被调度,也可以被抢占。实际上,内核线程只能由其他内核线程创建,在现有的内核线程中创建一个新的内核线程的方法:<br /><br />kthread_cre

星愿心愿的专栏 1552

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【回眸】Linux 内核 (十六) 之 多线程编程 下

前面介绍了互斥锁,本篇博文介绍死锁及其他多线程遇到的情况。

啤酒鸭的物联网开发记录博客 778

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Linux 内核编程第二部分(三)

在使用内核全局工作队列时,出现了一个简单的模式(工作流程):初始化工作任务。在适当的时间点,安排它执行(也许延迟和/或在特定的 CPU 核心上)。清理。通常,在内核模块(或驱动程序)的清理代码路径中,取消它。(最好是同步进行,以便首先完成任何待处理的工作任务。在这里,我们将坚持使用推荐的例程,避免使用flush_*()例程)。使用内核全局工作队列常规工作任务延迟工作任务在给定 CPU 上执行工作任务1. 初始化<立即或延迟都可以>2. 安排工作任务执行3. 取消(或刷新)它;

龙哥盟 1878

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Linux 多线程编程以及demo

Linux 多线程编程以及demo1.线程的概念从用户空间资源来看:从内核空间资源来看:2.线程的管理1.如何编译2.如何获取线程id(tid)3.demo3.线程创建1.参数介绍2.返回值3.demo4.线程退出与等待1.线程退出函数2.线程的取消线程能否被取消呢?demo 1.线程的概念 从用户空间资源来看: 线程不代表资源,是程序的最小执行单元------线程与线程间只是栈不同 进程代表资源,是程序调度的最小单元--------进程与进程是全复制 从内核空间资源来看: Linux应用层中

一只青木呀 827

Linux多线程

 一:Linux多线程编程:         线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者。传统的Unix也支持线程的概念,但是在一个进程(process)中只允许有一个线程,这样多线程就意味着多进程。现在,多线程技术已经被许多操作系统所支持,包括Windows/NT,当然,也包括Linux。  为什么有

stone_kingnet的专栏 3563

Linux多线程认识

Linux认识线程,线程控制笔记

JJR_YZ的博客 1045

透过 Linux 内核看无锁编程

透过 Linux 内核看无锁编程 http://www.ibm.com/developerworks/cn/linux/l-cn-lockfree/index.html 杨 小华, Linux 内核开发工程师, 自由撰稿人 杨小华,目前从事 Linux 内核方面的研

格物致知 771

java线程 kill linux_Java+Linux,深入内核源码讲解多线程之进程

之前写了两篇文章,都是针对Linux这个系统的,为什么?我为什么这么喜欢写这个系统的知识,可能就是为了今天的内容多线程系列,现在多线程不是一个面试重点 啊,那如果你能深入系统内核回答这个知识点,面试官会怎么想?你会不会占据面试的主动权(我不会说今天被一个面试者惊艳到了的)今天,我就开始一个系列的内容,多线程--高并发,深入的给大家讲解,我就不信讲不明白这么个小东西,有问题的地方希望大家能...

weixin_39630498的博客 103

linux杀死线程函数,Linux线程-pthread_kill

该函数可以用于向指定的线程发送信号:int pthread_kill(pthread_t threadId,int signal);如果线程内不对信号进行处理,则调用默认的处理程式,如SIGQUIT会退出终止线程,SIGKILL会杀死线程等等,可以调用signal(SIGQUIT, sig_process_routine); 来自定义信号的处理程序。传递的pthread_kill的signal参数...

weixin_33695631的博客 2666
上一篇: Linux内核延时研究与函数代码分析
下一篇: FWH_SEL1 的说明
flyingcloud_2008
博客等级 码龄19年 10粉丝 13原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值