Linux内核线程编程方法

Linux内核线程发生死锁或死循环后如何触发系统宕机重启 在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函数的第三个参数指定。


STM32F4系列HAL库配置定时器实验——输入捕获 STM32F4系列HAL库配置定时器实验——输入捕获 输入捕获简单讲解 输入捕获模式可以用来测量脉冲宽度或者测量频率。我们以测量周期和频率为例,用一个简图来说明输入捕获的原理 假定定时器工作在向上计数模式, 图中 t1~t2 时间,就是我们需要测量的高电平时间。测量方法如下:首先设置定时器通道 x 为 上升沿捕获,这样,t1 时刻,就会捕获到当前的 CNT 值,然后立即清零 CNT,并设置通道 x为下降沿捕获,这样到 t2 时刻,又会发生捕获事件,得到此时的 CNT 值,记为 CCRx2。这样,根据定时器 阅读详情

相关推荐

ESP32S3新手避坑:用IDF5.0驱动GT911触摸屏,我踩过的三个雷都给你填平了

本文详细解析了在ESP32S3开发板上使用IDF5.0驱动GT911触摸屏时常见的三大问题:软重启失效、状态寄存器读取异常和初始化参数差异。通过逻辑分析和硬件调试工具,提供了针对性的解决方案和优化建议,帮助开发者高效完成触摸屏驱动开发。

weixin_42567497的博客 297

linux 内核线程

linux 内核线程

一叶知秋的博客 718

ARM学习 | 紧耦合存储器 (TCM)

TCM 是一种专用的片上存储器,直接与处理器核心耦合。确定性访问:由于不涉及缓存替换或一致性管理,访问延迟固定。高带宽:TCM 通常通过专用总线连接处理器核心,可以提供更高的数据吞吐率。用户管理:TCM 的分配和管理完全由开发者控制,不依赖硬件缓存策略。ARM 处理器中的 TCM 通常分为ITCM(指令紧耦合存储器)和DTCM(数据紧耦合存储器),分别用于存储指令和数据。TCM 是 ARM 处理器中不可忽视的重要特性,在实时系统和高性能嵌入式应用中具有重要地位。

qq_43167806的博客 3329

linux驱动开发之内核线程

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

1686

rk3568 android 11.0 userdata 改为ext4格式

功能:解决设备在恢复出厂设置进行擦除数据的时候卡住问题。 1.修改userdata分区为ext4格式 diff --git a/device/rockchip/common/scripts/fstab_tools/fstab.in b/device/rockchip/common/scripts/fstab_tools/fstab.in index 583e75579d..036336835d 100755 --- a/device/rockchip/common/scripts/fstab_tools/

chgh1306的专栏 2576

西门子1200与FANUC机器人Profinet通讯

近期在做发那科FANUC的通讯,会吧CC-LINK、Profibus-DP、Profinet I/O、DeviceNet、EtherNet/IP这些常用通讯做成文档发上来,大家喜欢的话可以关注 注:做对应的通讯,在机器人控制柜都需要安装对应的板卡以及软件功能 PLC项目已经归档,只需要恢复就可以看到。对应Profinet通讯的GSD文件也都在博文最后有连接 机器人柜子:R-30IB Mate 机器人主体:M-10IA 12 一、硬件介绍 机器人Profinet I/O通讯板卡:...

七兔自习室 2万+

Linux内核多线程(一)

Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进程的种种合理以及不合理的请求)。内核需要多个执行流并行,为了防止可能的阻塞,支持多线程是必要的。内核线程就是内核的分身,一个分身可以处理一件特定事情。内核线程的调度由内核负责,一个内核线程处于阻塞状态时不影响其他的内核线程,因为其是调度的基本单位。这与用户线程是不一样的。因为内核线程只运行在内核态,因此,它只能使用大于PAGE_OFFS...

weixin_34186128的博客 691

1 四种防反接电路——multisim仿真

摘要:防反接电路可防止电源反接损坏器件,主要有四种方案:1)二极管串联(低成本,适用小电流);2)整流桥(无极性输入,但效率低);3)保险丝+稳压管(低损耗但需更换);4)MOS管方案(大电流、高效率,主流选择)。选型需考虑电流、压降和成本,MOS管因其低导通电阻(毫欧级)成为大电流应用的首选。口诀:"小电流二极管,大电流用MOS"可快速指导设计。

XU157303764的博客 1572

操作系统——内核级线程实现

操作系统 内核级线程创建

weixin_45864705的博客 814

74.9008深度刷机原理|高通QPST/Firehose底层刷写协议详解

移动设备刷机与底层维修技术指南 本文为移动设备维修人员和高级玩家提供全面的刷机与底层维修技术指南,涵盖高通、联发科和苹果A系列芯片的主要操作。 主要内容 核心操作:Bootloader解锁、Fastboot刷写、EDL深度修复、iTunes DFU模式恢复和分区表重建 适用场景:系统故障修复、底层损坏恢复、安全限制解除、系统降级和深度硬件维修 关键技术:详细解析刷机协议栈层级、关键分区作用和刷机安全机制 操作步骤: 环境搭建与驱动安装 Bootloader解锁(以小米为例) 高通机型系统刷写 苹果设备DFU

2601_95651806的博客 205

手把手教你安装 OpenClaw 小龙虾(MAC安装教程),一次成功不踩坑

本文详细介绍了在Mac上安装OpenClaw的完整流程。主要内容包括:1)准备工作(磁盘空间、网络环境、终端工具);2)安装Homebrew包管理器及常见问题解决;3)安装Node.js 22+版本(环境核心);4)Git安装与验证;5)OpenClaw项目克隆、依赖安装及运行配置;6)大模型配置方法(以MiniMax为例)。文章提供了详细的命令行操作步骤和常见错误解决方案,特别强调了网络环境要求和Apple Silicon芯片的原生支持注意事项。最后展示了验证配置成功的方法和资源获取渠道。

Chengbei11的博客 6340

9.内核级线程代码实现

1.本文内容总结自 B站 《操作系统-哈工大李治军老师》,内容非常棒,墙裂推荐;2.进程包括资源与执行序列,其中执行序列用线程来实现,线程分为用户线程和内核线程;进程中的资源管理主要是内存管理; 3.进程在操作系统的代码实现: 通过内核级代码 加上 内存管理代码 ;【补充】线程切换步骤: 1) fork:2 )fork代码的工作:3)具体代码 fork系统调用会展开为 例:__NR_write 是系统调用号,用来标识是哪种系统调用;.........

PacosonSWJTU的博客 1136

总结一下:电源设计 ≠ 画个电路图就完了

如果你面对一块电源板时,只知道输入输出是多少伏,那你离真正懂它还差十万八千里。你要懂拓扑、理解工作原理、看懂波形、会分析环路、熟练选型,还得懂调试、EMC和热设计——才能自信地说:“我会搞电源了。电源不是一个人能独挑的“电”,而是控制、模拟、热、EMC 多学科交融的“多面体”。这也是为什么它既复杂又迷人✨。

weixin_43199439的博客 144

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

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

星愿心愿的专栏 1552

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

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

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

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

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Linux内核线程

参考:https://blog.youkuaiyun.com/qq_15437667/article/details/69490325 https://blog.youkuaiyun.com/chen_1020/article/details/45789193 https://blog.youkuaiyun.com/gatieme/article/details/51566690 makefile 默认的情况下,make会在...

lyq_csdn的博客 901

老版QQ原生表情gif动态

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

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

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

龙哥盟 1878

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
上一篇: 使用find和xargs完成查找任务
下一篇: 为你自己找一个导师
kernel_learner
博客等级 码龄15年 60粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值