关于kthread_stop的疑问(linux3.16)

news2024/12/23 20:38:38

线程一旦启动起来后,会一直运行,除非该线程主动调用do_exit函数,或者其他的进程调用kthread_stop函数,结束线程的运行。

之前找销毁内核线程的接口时,发现了kthread_stop这个接口。网上说这个函数能够销毁一个内核线程。

最开始以为对于一个已经唤醒的内核线程,我们直接调用这个接口就能够让这个线程自动退出。后面经过试验发现并不是这样的======》kthread_stop只是通知线程退出,至于线程是否会退出,取决于线程的行为,即是否有kthread_should_stop动作,去检查,去主动退出

测试代码1

static struct task_struct *test_task;
struct task_struct *task;
struct timer_list timer;
int test_thread(void* a)
{
	printk(KERN_EMERG "\r\n thread start\n");
#ifdef CONFIG_PREEMPT_COUNT
	printk(KERN_EMERG "\r\n CONFIG_PREEMPT_COUNT\n");
#else
	printk(KERN_EMERG "\r\n not define CONFIG_PREEMPT_COUNT\n");
#endif	
	while (1)
    {
		if( kthread_should_stop())
		{
			printk(KERN_EMERG "\r\n exit while\n");
			break;
		}
		msleep(10000);	
	}
	printk(KERN_EMERG "\r\n thread end\n");
	return 0;
}
int kill_thread(void* a)
{
	if (NULL != test_task)
	{
		printk(KERN_EMERG "\r\n attempt kill test_thread\n");
		kthread_stop(test_task);
		printk(KERN_EMERG "\r\n kill test_thread complete\n");
	}
	return;
}
void timer_work(unsigned long data)
{
	wake_up_process(task);
	return;
}

static int smsc911x_init(struct net_device *dev)
{
................	
	timer.expires=jiffies+msecs_to_jiffies(20000);
	timer.function=timer_work;
	init_timer(&timer);
	add_timer(&timer);
	printk(KERN_EMERG "\r\n create thread\n");
	//spin_lock(&lockdep_test);
	test_task = kthread_create(test_thread, NULL, "test_task");
	wake_up_process(test_task); 
	task = kthread_create(kill_thread, NULL, "kill_task");
  	//kthread_stop(test_task);
	printk(KERN_EMERG "\r\n create thread end\n");
.....................
}

log如下:可以看到在上面的代码样例中(kthread_should_stop必须要有这个),确实能够让内核线程退出

测试代码2 

将内核线程的处理函数里面的kthread_should_stop去掉,其他保持不变。看看会发生什么

int test_thread(void* a)
{
	printk(KERN_EMERG "\r\n thread start\n");
#ifdef CONFIG_PREEMPT_COUNT
	printk(KERN_EMERG "\r\n CONFIG_PREEMPT_COUNT\n");
#else
	printk(KERN_EMERG "\r\n not define CONFIG_PREEMPT_COUNT\n");
#endif	
	while (1)
        {
		/*if( kthread_should_stop())
		{
			printk(KERN_EMERG "\r\n exit while\n");
			break;
		}*/
		msleep(10000);	
	}
	printk(KERN_EMERG "\r\n thread end\n");
	return 0;
}

log如下:可以看到。如果处理函数里面没有kthread_should_stop,即使通过kthread_stop通知内核线程应该退出了,但是内核线程不去检查是否应该退出,那么内核线程也是无法退出的。即kthread_stop是无法强制杀死内核线程的

测试 代码3

内核线程处理函数不要kthread_should_stop,在内核线程刚被创建并唤醒的时候,调用kthread_stop通知其退出。按照测试代码2,它应该不会主动退出的。但是实测这样是可以让内核线程退出的(甚至内核线程都没有被调度),这里没有想明白

static struct task_struct *test_task;
int test_thread(void* a)
{
	printk(KERN_EMERG "\r\n thread start\n");
#ifdef CONFIG_PREEMPT_COUNT
	printk(KERN_EMERG "\r\n CONFIG_PREEMPT_COUNT\n");
#else
	printk(KERN_EMERG "\r\n not define CONFIG_PREEMPT_COUNT\n");
#endif	
	while (1)
        {
		/*if( kthread_should_stop())
		{
			printk(KERN_EMERG "\r\n exit while\n");
			break;
		}*/
		msleep(10000);	
	}
	printk(KERN_EMERG "\r\n thread end\n");
	return 0;
}

static int smsc911x_init(struct net_device *dev)
{
........................	
	/*timer.expires=jiffies+msecs_to_jiffies(20000);
	timer.function=timer_work;
	init_timer(&timer);
	add_timer(&timer);*/
	printk(KERN_EMERG "\r\n create thread\n");
	//spin_lock(&lockdep_test);
	test_task = kthread_create(test_thread, NULL, "test_task");
	wake_up_process(test_task); 
	//task = kthread_create(kill_thread, NULL, "kill_task");
  	kthread_stop(test_task);
	printk(KERN_EMERG "\r\n create thread end\n");
......................................
}

log如下:可以看到内核线程打印的thread start,并且也搜到对应的内核线程

后面有时间研究一下这个是为什么

 使用注意事项

1、在执行kthread_stop的时候,目标线程必须没有退出,否则会Oops。原因很容易理解,当目标线程退出的时候,其对应的task结构也变得无效,kthread_stop引用该无效task结构就会出错。

2、内核线程的处理函数里面需要有kthread_should_stop,用于检查是否应该主动退出,否则线程是不会主动退出的。

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

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

相关文章

JavaScript:构造函数面向对象

JavaScript:构造函数&面向对象 构造函数实例化静态成员实例成员 内置构造函数引用类型基本含义常用属性方法ObjectArray 包装类型基本含义常用属性方法StringNumber 面向对象原型对象constructor对象原型原型链原型继承 构造函数 在讲解构造函数之前&#xff0…

[NISACTF 2022]bingdundun~

[NISACTF 2022]bingdundun~ wp 信息搜集 进入题目: 点一下 upload? : 注意看上面的 URL ,此时是 ?bingdundunupload 。 随便找个文件上传一下: 注意看上面的 URL ,此时变成:upload.php 。 那么我有理…

【力扣算法日记】无重复字符的最长子串

最近刷了很多算法题,这些解题过程也拓展了自己的思路,是个适合记录的素材。所以决定在继技术知识点详解的【一文系列】之后,开启新坑——【力扣算法系列】,来记录力扣刷题过程。 分享题目不确定,目前打算只分享我认为…

聊一聊 .NET高级调试 内核模式堆泄露

一:背景 1. 讲故事 前几天有位朋友找到我,说他的机器内存在不断的上涨,但在任务管理器中查不出是哪个进程吃的内存,特别奇怪,截图如下: 在我的分析旅程中都是用户态模式的内存泄漏,像上图中的…

【JVM】类加载器ClassLoader

一、简介 在Java中,类加载器(ClassLoader)是一个关键的组件,它负责将字节码文件加载到内存并转换成Java类。Java的类加载器主要可以分成两类:系统提供的和由Java应用开发人员编写的。Java开发者可以根据需要创建自己的…

ES集群分片数据的高可用

文章目录 ES集群分片数据的高可用1. 集群设置索引节点2. 集群新增文档数据3.查看集群中文档数据分片节点4. 让节点9201宕机,查看其分片变化5. 让节点9201,查看分片变化 ES集群分片数据的高可用 集群中的索引主分片和副分片在不同的计算机上,如…

揭开 JavaScript 作用域的神秘面纱(下)

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

pyqtgraph 教程

pyqtgraph 教程 简介 PyQtGraph 是一个用于科学和工程数据可视化的开源库,基于 PyQt 和 NumPy 构建而成。它提供了丰富的绘图工具和交互功能,可以用于创建高性能的实时数据图表、图像显示和信号处理应用。 以下是 PyQtGraph 的一些特点和功能&#xf…

.NET Standard 支持的 .NET Framework 和 .NET Core

.NET Standard 是针对多个 .NET 实现推出的一套正式的 .NET API 规范。 推出 .NET Standard 的背后动机是要提高 .NET 生态系统中的一致性。 .NET 5 及更高版本采用不同的方法来建立一致性,这种方法在大多数情况下都不需要 .NET Standard。 但如果要在 .NET Framewo…

基于sumo实现交通灯控制算法的模板

基于sumo实现交通灯控制算法的模板 目录 在windows安装run hello world networkroutesviewsettings & configurationsimulation 交通灯控制系统 介绍文件生成器类(FileGenerator)道路网络(Network)辅助函数生成道路网络&am…

从细菌基因组中提取噬菌体变异序列工具PhaseFinder的介绍、安装和使用方法

PhaseFinder ## 概览,不翻译了,大家自己看吧 The PhaseFinder algorithm is designed to detect DNA inversion mediated phase variation in bacterial genomes using genomic or metagenomic sequencing data. It works by identifying regions flank…

Java学习笔记(四)——正则表达式

文章目录 正则表达式基本规则字符类(只匹配一个字符)预定义字符(只匹配一个字符)数量词练习正则表达式插件 爬虫利用正则表达式获取想要的内容爬取网络信息练习有条件的爬取贪婪爬取非贪婪爬取正则表达式在字符串中的使用 分组捕获分组正则表达式外部使用非捕获分组正则表达式忽…

公共用例库计划--个人版(二)主体界面设计

1、任务概述 计划内容:完成公共用例库的开发实施工作,包括需求分析、系统设计、开发、测试、打包、运行维护等工作。 1.1、 已完成: 需求分析、数据库表的设计:公共用例库计划–个人版(一) 1.2、 本次待…

神经网络-卷积层

卷积 输入通道数, 输出通道数,核大小 参数具体含义 直观理解各个参数的网站(gif) https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md大概长这样,cyan是青色的意思 channel数(终于理解论文里图片放好多层的原因…

VMware ESXI 8 安装ipmitool 调整戴尔服务器风扇转速

本文内容适合ESXI 8版本安装ipmitool ,进行管理,已知的是8.0以上版本无法安装社区的vib.所以需要自己编译文件,7.0及之前的版本可以安装vib版本的ipmtools。 一、编译好的适用于esxi8的ipmitool下载 ipmitool下载 二、安装ipmitool 1、开…

铁塔基站数字化管理监测解决方案

截至2023年10月,我国5G基站总数达321.5万个,占全国通信基站总数的28.1%。然而,随着5G基站数量的快速增长,基站的能耗问题也逐渐日益凸显,基站的用电给运营商带来了巨大的电费开支压力,降低5G基站的能耗成为…

new FormData 同时发送表单 json 以及文件二进制流

需要新增时同时发送表单 json 以及对应的文件即可使用以下方法传参 let formDataParams new FormData(); 首先通过 new FormData() 创建你需要最后发送的表单 接着将你的对象 json 存储,注意使用 new Blob 创建大表单转换成 json 格式。以…

根据MySql的表名,自动生成实体类,模仿ORM框架

ORM框架可以根据数据库的表自动生成实体类,以及相应CRUD操作 本文是一个自动生成实体类的工具,用于生成Mysql表对应的实体类。 新建Winform窗体应用程序AutoGenerateForm,框架(.net framework 4.5), 添加对System.Configuration的…

了解nginx

1,概念 nginx是一个轻量级、高性能的HTTP和反向代理web服务器,同时也是一个通用代理服务器(TCP、UDP、IMAP、POP3、SMTP)。 2,优势 轻量级,占用内存少,启动极快采用事件驱动的异步非阻塞处理方…

linux中的系统安全

一.账号安全 将非登录用户的shell设为/sbin/nologin 系统中用户有三种:超级管理员 普通用户 程序用户 前两种用户可以登录系统,程序用户不给登录 所以称为非登录用户 命令格式: usermod -s /sbin/nologin(改已有用户&#…