Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >聊聊内核中关键的概念之上篇

聊聊内核中关键的概念之上篇

作者头像
用户4700054
发布于 2022-08-17 05:11:37
发布于 2022-08-17 05:11:37
30300
代码可运行
举报
运行总次数:0
代码可运行

虚拟地址空间

  • 内核在进程和物理内存之间提供了一层抽象层,这一层是虚拟地址空间,进程的内存视图是通过虚拟地址空间构建的。虚拟地址空间为进程提供了假象(虚拟内存),每个进程以为自己在执行过程中独占了整个内存,虚拟内存是由内核的内存管理和CPU的MMU协调实现的。每个进程都会有32位或者64位的地址空间,这个地址空间范围是由系统结构所限定的。每个进程通过MMU加载到虚拟地址空间中,任何进程尝试方位其边界之外的地址空间都会触发硬件故障,从而使内存管理器能够检测和终止违反的进程(Segment Fault错误)。

用户空间和内核空间

  • Linux操作系统将整个内存分割为两个逻辑分区:用户空间和内核空间。这种分开设计确保所有分配有地址空间的进程都映射到内存的用户空间,而内核数据和服务都在内核空间中运行。内核通过与硬件协调实现这种保护。当应用程序发起syscall(系统调用),CPU切换为特权模式,从用户空间切换到内核空间,所请求的服务完成后,内核使用了另外一组CPU指令将进程从内核空间切换到用户空间。

上下文切换

  • 当一个进程通过系统调用请求内核服务时,内核将代表调用进程来执行,此时内核被认为是进程上下文中执行,上下文切换是指进程存储一个进程或者线程的状态,然后完成某种服务后恢复和唤醒进程的执行点,这个上下文切换是由时间开销的,保存旧进程的状态(拷贝当前进程涉及到的寄存器的状态到PCB),加载已经保存进程状态的新进程(从进程的PCB中拷贝到寄存器中),上下文切换时间时依赖于硬件。

进程描述符

  • 进程从创建到退出过程都是有内核的进程管理子系统进行管理。一个进程在内存中还被分配一个称为描述符的数据结构,内核用进程描述符来识别、管理和调度进程。内核定义了struct task_struct类型描述一个进程的实例,包括进程所有的属性。标识的详细信息、资源分配的情况。
  • 一个进程从产生到退出一直出于不同的状态中,这个也叫做进程状态,它们定义了进程当前不同的状态。TASK_RUNNING是进程正在执行或在调度器运行队列中的抢占CPU;TASK_INTERRUPTIBLE是进程出于可中断的等待状态,它依旧出于等待状态知道所有等待条件为真,例如互斥锁调用、IO准备等。TASK_KILLABLE这个于TASK_INTERRUPTIBLE类似,不同的TASK_KILLABLE只会发生在致命信号上。TASK_UNINTERRUPTIBLE是进程处于不可中断的等待状态,进程处于这种状态不会被产生的信号唤醒,只有它正在等待的事件发生时候进程才转换为TASK_RUNNING状态。TASK_STOPPED是进程已经收到终止的信号,进程终止;TASK_TRACED是一个进程可能被一个调试器进行检查,这时候可认为进程出于这个状态;TASK_ZOMBIE是进程碑额终止,但是进程的资源尚未回收;EXIT_DEAD是父进程使用wait方法收集子进程的退出状态后,子进程终止,并且释放它的所有资源.
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct task_struct {
#ifdef CONFIG_THREAD_INFO_IN_TASK

	// 保存处理器特定的状态信息,并且它是任务结构体的关键信息 
	struct thread_info		thread_info;
#endif
	/* -1 unrunnable, 0 runnable, >0 stopped: */
	volatile long			state;

	/*
	 * This begins the randomizable portion of task_struct. Only
	 * scheduling-critical items should be added above here.
	 */
	randomized_struct_fields_start

	void				*stack;
	atomic_t			usage;
	// 进程相应的各种属性,字段中每一位对应于一个进程生命周期中的各个字段。
	unsigned int			flags;
	unsigned int			ptrace;

#ifdef CONFIG_SMP
	struct llist_node		wake_entry;
	int				on_cpu;
#ifdef CONFIG_THREAD_INFO_IN_TASK
	/* Current CPU: */
	unsigned int			cpu;
#endif

	// prio和static_prio,prio帮助确定调度进程的优先级,如果进程被分配了实时调度策略,则噶字段保存静态优先级,范围是1~99.对于正常进程,这个字段保存了由nice的值得来的动态优先级
	int				prio;
	int				static_prio;
	int				normal_prio;
	// 指定实时调度策略的进程优先级
	unsigned int			rt_priority;

	const struct sched_class	*sched_class;
	// se/rt/dk 是每个任务属于的调度实体,因为调度是在每个实体级别的完成的。se用于所有正常进程;rt是用于实时进程;dl用于截止期进程。
	struct sched_entity		se;
	struct sched_rt_entity		rt;
#ifdef CONFIG_CGROUP_SCHED
	struct task_group		*sched_task_group;
#endif
	struct sched_dl_entity		dl;

#endif
	// 该字段保存和进程调度策略相关信息
	unsigned int			policy;
	int				nr_cpus_allowed;
	// 该字段制定了进程的CPU掩码,在多处理器系统中,进程允许在哪个CPU上进行调度
	cpumask_t			cpus_allowed;

	// pid是进程的唯一标识符,它是pid_t类型,可以通过/proc/sys/kernel/pid_max接口制定默认的最大值,默认最大值是2的32次方大约400万
	pid_t				pid;
	// 保存线程组id,假设创建一个新进程,它的pid和tgid是相同的。当进程产生一个新线程时候,新的子进程将获得唯一的pid
	pid_t				tgid;

	// 对于正常进程,real_parent和parent两个指针指向同一个task_struct,它们区别仅在于使用posix线程实现的多线程进程,对于这种情况,real_parent指向父进程的结构,parent指向收到SIGCHLD信号的进程任务的结构体
	struct task_struct __rcu	*real_parent;
	struct task_struct __rcu	*parent;
	// 指向子任务结构体链表的指针
	struct list_head		children;
	// 指向兄弟任务结构体链表的指针
	struct list_head		sibling;
	// 指向进程组组长的结构体
	struct task_struct		*group_leader;

	// 存储了文件系统信息
	struct fs_struct		*fs;

	// 文件描述符保存了一些指针,这些指针指向进程为了执行各个操作而打开的所有文件
	struct files_struct		*files;

	/* Namespaces: */
	struct nsproxy			*nsproxy;

	/* CPU-specific state of this task: */
	struct thread_struct		thread;


};
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 存储内核技术交流 微信公众号,前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Linux内核进程原理
进程是指计算机中已运行的程序。进程本身不是基本的运行单位,而是线程的容器。程序本身只是指令、数据及组织形式的描述,而进程才是程序真正的运行实体。在Linux内核中,进程又称为任务(task),进程的虚拟地址空间可以分为用户虚拟地址空间和内核虚拟地址空间,所有进程共享内核虚拟地址空间,又各自拥有独立的用户虚拟地址空间。
laputa
2022/11/13
2.2K0
【Linux进程】初悉进程
在Linux中,进程是最基本的执行单位。进程调度在整个操作系统中属于核心地位,是操作系统实现多任务处理的关键操作,确保每个进程在有限的CPU资源下有序的完成相应操作。
小文要打代码
2025/01/09
2350
【Linux进程】初悉进程
Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)
因此当前linux的调度程序由两个调度器组成:主调度器,周期性调度器(两者又统称为通用调度器(generic scheduler)或核心调度器(core scheduler))
233333
2018/12/06
4.5K1
Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)【转】
Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息。它定义在include/linux/sched.h文件中。
233333
2018/09/14
2.4K0
Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)【转】
【Linux】深入理解进程管理与高效运用
        进程是正在运行的程序实例,在Linux内核中,进程被称为任务,例如内核线程与用户线程等。
小文要打代码
2025/03/18
1580
task_struct结构详解
在 Linux 内核中,无论是进程还是线程,到了内核里面,都叫做任务(Task),由统一的数据结构 task_struct 进行管理。task_struct 是 Linux 中的进程描述符,是感知进程存在的唯一实体。Linux 内核中通过一个双向循环链表将所有的 task_struct 串了起来,不同的操作系统中,PCB 所包含的内容也会不同。
小文要打代码
2025/04/01
1080
Linux调度原理介绍和应用(前篇)
提示:公众号展示代码会自动折行,建议横屏阅读 摘要 本文(有码慎入)主要介绍Linux任务调度相关的发展历史和基本原理。多年以来,内核界的黑客们一直着力于寻找既能满足高负载后台任务资源充分利用,又能满足桌面系统良好交互性的调度方法,尽管截至到目前为止仍然没有一个完美的解决方案。本文希望通过介绍调度算法的发展历程,因为任务调度本身不是一个局限于操作系统的话题,包括数据库,程序语言实现等,都会与调度相关。本文在介绍过程中,会引用Linux的代码实现作为说明,同时阐述其中的一些趣闻轶事。 调度实体 进程任务通常包
腾讯数据库技术
2018/07/26
1.4K0
一个小实验巩固下进程管理
通过这三篇文章的学习我们知道,无论内核进程还是用户进程,都是可以用task_struct来描述的,那么本篇我们实践下如何通过task_struct字段把系统中所有的进程包含的信息打印出来,比如:属性信息,状态,进程标识符,优先级信息,亲属关系,文件系统信息,内存方面的信息等。
刘盼
2020/05/08
8250
一个小实验巩固下进程管理
深入理解Linux内核进程上下文切换
韩传华,就职于南京大鱼半导体有限公司,主要从事linux相关系统软件开发工作,负责Soc芯片BringUp及系统软件开发,乐于分享喜欢学习,喜欢专研Linux内核源代码。
Linux阅码场
2020/10/10
10.7K0
深入理解Linux内核进程上下文切换
【Linux 内核 内存管理】虚拟地址空间布局架构 ⑤ ( Linux 内核中对 “ 虚拟地址空间 “ 的描述 | task_struct 结构体源码 )
进程 的 " 虚拟地址空间 " 由 mm_struct 和 vm_area_struct 两个数据结构描述 ;
韩曙亮
2023/03/30
3.8K0
【Linux 内核 内存管理】虚拟地址空间布局架构 ⑤ ( Linux 内核中对 “ 虚拟地址空间 “ 的描述 | task_struct 结构体源码 )
《Linux内核分析》之分析fork函数对应的系统调用处理过程
xref: /linux-3.18.6/include/linux/sched.h
WindCoder
2018/09/20
1.1K0
《Linux内核分析》之分析fork函数对应的系统调用处理过程
全新系列-Linux进程管理初探
大家好,我是程栩,一个专注于性能的大厂程序员,分享包括但不限于计算机体系结构、性能优化、云原生的知识。
程栩的性能优化笔记
2023/11/01
2990
全新系列-Linux进程管理初探
Linux进程管理(一)进程数据结构
Linux内核中使用 task_struct 结构来表示一个进程,这个结构体保存了进程的所有信息,所以它非常庞大,在讲解Linux内核的进程管理,我们有必要先分析这个 task_struct 中的各项成员
用户6280468
2022/06/09
1.3K0
Linux进程管理(一)进程数据结构
聊聊Linux中线程和进程的联系与区别!
关于进程和线程,在 Linux 中是一对儿很核心的概念。但是进程和线程到底有啥联系,又有啥区别,很多人还都没有搞清楚。
开发内功修炼
2022/12/07
2.4K0
聊聊Linux中线程和进程的联系与区别!
一文看懂 | fork 系统调用
Unix标准的复制进程的系统调用时fork(即分叉),但是Linux,BSD等操作系统并不止实现这一个,确切的说linux实现了三个,fork,vfork,clone(确切说vfork创造出来的是轻量级进程,也叫线程,是共享资源的进程)
用户7686797
2021/10/20
2.6K0
sched.h (版本4.16.7全部内容)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/03
3940
Linux进程是如何创建出来的?
在 Linux 中,进程是我们非常熟悉的东东了,哪怕是只写过一天代码的人也都用过它。但是你确定它不是你最熟悉的陌生人?我们今天通过深度剖析进程的创建过程,帮助你提高对进程的理解深度。
开发内功修炼
2022/12/07
2.2K0
Linux进程是如何创建出来的?
Linux 进程管理
在内核层面,每个进程都是由task_struct 描述的,这个结构体非常大,可以粗略看下各主要内容:
一只小虾米
2023/03/09
10.2K0
Linux 进程管理
吐血整理 | 肝翻 Linux 进程调度所有知识点
前面我们重点分析了如何通过 fork, vfork, pthread_create 去创建一个进程或者线程,以及后面说了它们共同调用 do_fork 的实现。现在已经知道一个进程是如何创建的,但是进程何时被执行,需要调度器来选择。所以这一节我们介绍下进程调度和进程切换的详情。
刘盼
2021/12/13
2K0
吐血整理 | 肝翻 Linux 进程调度所有知识点
【Linux 内核】进程管理 ( 内核线程概念 | 内核线程、普通进程、用户线程 | 内核线程与普通进程区别 | 内核线程主要用途 | 内核线程创建函数 kernel_thread 源码 )
" 内核线程 " 是一种 特殊进程 , 独立运行在 " 内核空间 " , 其将 " 内核函数 " 委托给 独立进程 , 该 " 独立进程 " 与 其它进程 ( 包括 普通进程 , 内核自身 , 用户级线程 ) 并行执行 ;
韩曙亮
2023/03/30
4.2K0
【Linux 内核】进程管理 ( 内核线程概念 | 内核线程、普通进程、用户线程 | 内核线程与普通进程区别 | 内核线程主要用途 | 内核线程创建函数 kernel_thread 源码 )
推荐阅读
相关推荐
Linux内核进程原理
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验