前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Linux 内核】进程管理 ( 内核线程概念 | 内核线程、普通进程、用户线程 | 内核线程与普通进程区别 | 内核线程主要用途 | 内核线程创建函数 kernel_thread 源码 )

【Linux 内核】进程管理 ( 内核线程概念 | 内核线程、普通进程、用户线程 | 内核线程与普通进程区别 | 内核线程主要用途 | 内核线程创建函数 kernel_thread 源码 )

作者头像
韩曙亮
发布2023-03-30 13:49:01
3.8K0
发布2023-03-30 13:49:01
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

一、内核线程概念


直接 由 Linux 内核 启动的线程 , 被称为 " 内核线程 " ;

" 内核线程 " 是一种 特殊进程 , 独立运行在 " 内核空间 " , 其将 " 内核函数 " 委托给 独立进程 , 该 " 独立进程 " 与 其它进程 ( 包括 普通进程 , 内核自身 , 用户级线程 ) 并行执行 ;

" 内核线程 " 也称为 " 守护进程 " ;

二、内核线程、普通进程、用户线程


【Linux 内核】进程管理 ( 进程特殊形式 | 内核线程 | 用户线程 | C 标准库与 Linux 内核中进程相关概念 | Linux 查看进程命令及输出字段解析 ) 一、进程特殊形式 ( 内核线程 | 用户线程 ) 博客章节 , 有介绍内核线程 ,

普通的进程 , 包含 内核虚拟地址空间 和 用户虚拟地址空间 , 其中 内核虚拟地址空间 所有进程共享 , 用户虚拟地址空间 由进程独立拥有 ; 除了 普通进程 外 , 进程 还有

2

种 特殊形式 :

  • 内核级线程 : 只有 内核虚拟地址空间 , 没有 用户虚拟地址空间 的进程 , 称为 内核线程 ;
  • 用户级线程 : 共享 用户虚拟地址空间 的进程 , 称为 用户线程 ;

三、内核线程、普通进程区别


" 内核线程 " 与 " 普通进程 " 区别是 , 内核进程 没有 " 独立的进程地址空间 " ;

task_struct 进程描述符 结构体中的 , mm 指针指向的空间就是 " 独立的进程地址空间 " ;

在 Linux 内核 中 , " 进程控制块 " 是通过 task_struct 结构体 进行描述的 ; Linux 内核中 , 所有 进程管理 相关算法逻辑 , 都是基于 task_struct 结构体的 ; task_struct " 进程描述符 " 结构体在 linux-5.6.18\include\linux\sched.h 头文件中 第

629

~

1300

行定义 ;

mm 字段是一个指针 , 指针指向 mm_struct 结构体 , 这是 " 内存描述符 " , 与 tsak_struct 进程描述符性质相似 ;

对于 进程 来说 , active_mm 字段 与 mm 字段 指向同一个 " 内存描述符 " ;

但对于 " 内核线程 " 来说 , mm 字段 指向 空指针 , active_mm 字段 指向 从进程借用的 " 内存描述符 " ;

代码语言:javascript
复制
	struct mm_struct		*mm;
	struct mm_struct		*active_mm;

源码地址 : linux-5.6.18\include\linux\sched.h

四、内核线程主要用途


内核线程主要用途 :

内存同步 : 周期性执行如下同步操作 , 同步 " 修改的内存页 " 与 " 页来源块设备 " , 如 : mmap 文件映射 ;

写交换区 : 假如同步 " 修改的内存页 " 与 " 页来源块设备 " 时 , 内存页使用率很低 , 则 将同步内容写入 " 交换区 " ;

延时管理 : 管理 " 延时动作 " , Deferred Action ;

系统日志 : 管理控制 文件系统 事务日志 生成 ;

五、内核线程创建函数 kernel_thread 源码


linux-5.6.18\kernel\fork.c 源码中的

代码语言:javascript
复制
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)

方法 , 就是创建内核线程的函数 , 该函数中最终也是调用了 _do_fork() 函数 , 与 fork() , vfork() , clone() 等系统调用函数创建进程的方式类似 ;

代码语言:javascript
复制
/*
 * Create a kernel thread.
 */
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
	struct kernel_clone_args args = {
		.flags		= ((lower_32_bits(flags) | CLONE_VM |
				    CLONE_UNTRACED) & ~CSIGNAL),
		.exit_signal	= (lower_32_bits(flags) & CSIGNAL),
		.stack		= (unsigned long)fn,
		.stack_size	= (unsigned long)arg,
	};

	return _do_fork(&args);
}
在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、内核线程概念
  • 二、内核线程、普通进程、用户线程
  • 三、内核线程、普通进程区别
  • 四、内核线程主要用途
  • 五、内核线程创建函数 kernel_thread 源码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档