Linux内核重要的5个子系统-进程调度(SCHED) - 蜻蜓墓园

Linux内核重要的5个子系统-进程调度(SCHED)

  linux内存布局图_linux内存管理图_linux内存管理源码剖析

  架构的上半部分是用户(或应用程序)空间,这是用户应用程序执行的地方。 用户空间下面是内核空间,Linux内核所在的位置。

  Linux内核可以进一步分为3层:最上面是系统调用接口。 用户程序被软件中断后,调用系统内核提供的函数。 用户空间和内核提供的服务之间的这种接口称为系统调用。 它实现了一些基本的功能,比如读、写,都是系统调用;

  系统调用接口下面是内核代码,可以更准确地定义为与体系结构无关的内核代码。 这些代码对于 Linux 支持的所有处理器架构都是通用的;

  内核代码下面是依赖于体系结构的代码,形成通常所说的 BSP(板支持包),它充当给定体系结构的处理器和依赖于特定硬件结构的特定于平台的代码。

  那么我们来看看Linux内核的五个子系统:

  Linux内核主要由进程调度(SCHED)、内存管理(MM)、虚拟文件系统(VFS)、网络接口(NET)和进程间通信(IPC)五个子系统组成。 每一项都非常重要,缺一不可。 如下所示。

  linux内存管理图_linux内存布局图_linux内存管理源码剖析

  Linux内核的组成和关系

  【文章福利】小编推荐自己的Linux内核技术交流群:【977878001】整理一些我个人认为比较好的学习书籍和视频资料,在群文件里分享。 如果有需要的话,可以自己添加! ! ! 前100人进群将额外获得价值699的核心资料包(含视频教程、电子书、实战项目和代码)

  linux内存布局图_linux内存管理图_linux内存管理源码剖析

  内核资料直通车:Linux内核源码技术学习路线+视频教程代码资料

  直接学习:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈

  进程调度

  进程调度控制系统中多个进程对CPU的访问,使多个进程可以在CPU中“微串行、宏并行”执行。 进程调度是系统的中心,内核中的其他子系统都依赖于它,因为每个子系统都需要挂起或恢复进程。

  linux内存管理源码剖析_linux内存管理图_linux内存布局图

  Linux进程状态转换

  如上图所示,Linux进程在几种状态之间切换。 在设备驱动程序编程中,当所请求的资源无法满足时,驱动程序通常会调度其他进程执行,并使进程进入睡眠状态。 直到它请求的资源被释放后,它才会被唤醒并进入就绪状态。 睡眠分为可中断睡眠和不可中断睡眠。 两者的区别在于,可中断睡眠会在收到信号时被唤醒。

  在设备驱动程序编程中,当所请求的资源无法满足时,驱动程序一般会调度其他进程执行,相应的进程就会进入睡眠状态。 直到它请求的资源被释放后,它才会被唤醒并进入就绪状态。 在设备驱动程序中,如果需要多个并发执行的任务,可以启动内核线程。 启动内核线程的函数是:

  pid_t kernel_thread(int (fn)(void ), void *arg, 无符号长标志);

  当用户使用系统提供的库函数进行进程编程时,用户可以动态创建进程,进程之间存在等待、互斥等操作。 这些操作都是由Linux内核实现的。 Linux内核通过进程管理子系统来实现进程相关的操作。 在Linux系统上,所有的计算工作都是通过进程来完成的。 该过程可以是短期的(执行命令)或长期的(网络服务)。 Linux系统是一个动态系统,可以通过进程管理来适应不断变化的计算需求。

  在用户空间中,进程由进程标识符(PID)表示。 从用户的角度来看,PID 是唯一标识进程的数值。 PID值在进程的整个生命周期内不会改变,但进程销毁后PID可以重新使用。 创建流程有多种方法。 您可以创建新进程或创建当前进程的子进程。

  在Linux内核空间中,每个进程都有一个独立的数据结构,用于保存进程的ID、优先级、地址空间等信息。 该结构也称为进程控制块。 所谓进程管理就是对进程控制块的管理。

  Linux进程是通过fork()函数系统调用生成的。 调用fork()的进程称为父进程,产生的进程称为子进程。 子进程创建时,除了进程ID外,其他数据结构与父进程完全相同。 fork()系统调用创建内存后,立即将子进程添加到内核的进程调试队列中,然后使用exec()系统调用将程序代码添加到子进程的地址空间中,然后子进程开始执行自己的代码。 。

  一个系统上可以有多个进程,但一般只有一个CPU,同时只能有一个进程在工作。 即使有多个CPU,也不可能有那么多进程。 如果多个进程可以在CPU上工作,这就是进程管理子系统的工作。 Linux内核设计了一个结构体来存储进程队列。 系统上会有多个队列来存储不同状态的进程。 一个进程可以有多种状态,这些状态是由操作系统定义的,但它至少包含三种状态:运行状态、就绪状态和等待状态。 内核设计了相应的队列来存储相应状态的进程控制块。

  当用户进程被加载时,它将进入就绪状态并被添加到就绪队列中。 CPU时间轮转到就绪队列后,切换到进程的代码。 该过程被执行。 当达到进程的时间片时,将其换出。 。 如果进程中发生I/O操作,则会提前换出并放入等待队列中。 当I/O请求返回时,进程将被放入就绪队列中。 Linux系统设计了几种不同的方法来管理进程队列。 主要目的是提高工艺调试的稳定性。

  内存管理

  内存管理的主要作用是控制多个进程安全地共享主内存区域。 Linux内存管理在CPU提供内存管理单元(MMU)的情况下,完成每个进程的虚拟内存到物理内存的转换。 Linux 2.6 引入了对无 MMU CPU 的支持。

  如下图3所示,一般来说,Linux中的每个进程享有4GB的内存空间,0到3GB属于用户空间,3到4GB属于内核空间。 内核空间用于常规内存、I/O 设备内存和高端内存。 不同的处理方式。

  linux内存布局图_linux内存管理源码剖析_linux内存管理图

  Linux进程地址空间

  对于采用虚拟内存技术的计算机来说,内存管理硬件以分页的方式管理内存。 分页方法将计算机系统的物理内存划分为相同大小的相等部分。 每个内存片段称为一个内存页。 通常内存页大小为4KB。 Linux内核的内存管理子系统管理虚拟内存和物理内存之间的映射关系,以及系统的可用内存空间。 内存管理必须管理的不仅仅是 4KB 缓冲区。 Linux 提供了 4KB 缓冲区的抽象,例如slab 分配器。 这种内存管理模式使用 4KB 缓冲区作为基础,然后从中分配结构并跟踪内存页使用情况,例如哪些内存页已满、哪些页未完全使用以及哪些页为空。 这允许该模式根据系统需求动态调整内存使用情况。

  在支持多用户的系统上,由于内存使用量的增加,很容易导致物理内存被耗尽。 为了解决物理内存耗尽的问题,内存管理子系统提供了可以将页面从内存移出并放置到磁盘上的功能,这个过程称为交换。 内存管理的源代码可以在./linux/mm中找到。

  虚拟文件系统

  如下图4所示,Linux虚拟文件系统(VFS)隐藏了各种硬件的具体细节,并为所有设备提供了统一的接口。 而且,它独立于各个具体的文件系统,是各种文件系统的抽象。 它使用超级块来存储文件系统相关信息,使用索引节点inode来存储文件的物理信息,使用目录项dentry来存储文件。 逻辑信息。

  linux内存管理图_linux内存管理源码剖析_linux内存布局图

  Linux文件系统

  在不同格式的文件分区上,程序都能正确读写文件,而且结果是一样的。 有时在使用Linux系统时,发现不同类型的文件分区中可以直接复制文件。 对于应用程序来说,它不知道文件系统的类型,甚至不知道文件的类型。 这就是虚拟文件系统在幕后所做的事情。 工作。 虚拟文件系统屏蔽了不同文件系统之间的差异,为用户提供了统一的界面。

  虚拟文件系统,即VFS(Virtual File System),是Linux内核中的一个软件抽象层。 它通过一些数据结构和方法,提供与实际文件系统如ext2、vfat等的接口机制。 通过使用同一套文件I/O系统调用,可以对Linux中的任何文件进行操作,而无需考虑其所在的具体文件系统格式; 进一步地,可以在不同的文件系统之间进行文件操作。 在Linux系统中,一切都可以被视为文件。 不仅普通的文本文件和目录可以作为文件处理,字符设备、块设备、套接字等也可以作为文件处理。 这些文件虽然类型不同,但使用的操作方法是相同的。 这也是UNIX/Linux设计的基本理念之一。

  虚拟文件系统(简称VFS)是实现“一切皆文件”特性的关键。 它是Linux内核的一个软件层,为用户空间程序提供文件系统接口; 它还在内核中提供了一个抽象函数,允许不同类型的文件系统存在。 VFS可以理解为一种抽象接口标准。 系统中的所有文件系统不仅依靠VFS共存,而且还依靠VFS协同工作。 为了支持不同的文件系统,VFS定义了所有文件系统都支持的最基本的概念接口和数据结构。 在实现具体的文件系统时,需要为VFS提供符合VFS标准的接口和数据结构。 数据结构,不同的文件系统可能在实体概念上有差异,但是在使用VFS接口时,需要与VFS定义的概念保持一致。 只有这样才能实现用户的文件系统独立性。 VFS隐藏了具体文件系统的操作细节,因此从VFS层和内核其他部分的角度来看,所有文件系统都是相同的。 文件系统访问的系统调用通过VFS 软件层进行处理。 VFS根据访问请求调用不同的文件系统驱动函数来处理用户请求。 当文件系统代码访问物理设备时,需要使用物理设备驱动程序来访问真实的硬件。

  网络接口

  网络接口提供对各种网络标准的访问以及对各种网络硬件的支持。 如下图所示,Linux中的网络接口可以分为网络协议和网络驱动程序。 网络协议部分负责实现每一种可能的网络传输协议。 网络设备驱动程序负责与硬件设备进行通信。 每一种可能的硬件设备都有相应的设备驱动程序。

  linux内存管理图_linux内存布局图_linux内存管理源码剖析

  Linux网络架构

  编写网络应用程序并使用套接字通过 TCP/IP 协议与其他机器进行通信。 与前面介绍的内核子系统类似,socket相关的功能也是通过内核子系统完成的。 内核的网络子系统负责这部分任务。 ,这部分代码有时被称为“网络堆栈”。 Linux内核提供了优秀的网络处理能力和功能,这与网络栈代码的设计思想是分不开的。 Linux的网络栈部分遵循传统的层次结构。 网络数据从用户进程到达实际网络设备需要四个步骤。 级别:用户进程、套接字、网络协议和网络设备。

  事实上,每一层又可以分为很多层次。 数据传输路径是基于层级的,不能跨越某个层级。 Linux网络子系统对于网络层面采用了类似面向对象的设计思想,将需要处理的层面抽象为不同的实体,并定义了实体之间的关系和数据处理过程:

  (1)网络协议:网络协议可以理解为一种语言,用于网络中不同设备之间的通信,是一种通信规范。

  (2) 套接字:套接字是内核和用户程序之间的接口。 套接字对应一个数据连接,为用户提供文件I/O。 用户可以像操作文件一样在数据连接上发送和接收数据。 具体的协议处理由网络协议部分来处理。 套接字是用户使用网络的接口。

  (3)设备接口:设备接口是网络子系统中软件与硬件之间的接口。 用户数据最终需要通过网络硬件设备进行发送和接收。 网络设备千差万别,设备驱动程序也各不相同。 它们通过设备接口被阻止。 特定设备驱动程序的差异。

  (4)网络缓冲区:网络缓冲区又称为套接字缓冲区(sk_buff),是网络子系统中的重要结构体。 网络传输数据存在很多不确定因素。 除了物理设备对数据传输的限制(如MMU)外,网络干扰、丢包、重传等都会造成数据不稳定。 网络缓冲区重新组织网络数据。 使业务处理数据包完整。 网络缓冲区是内存中的缓冲区,是网络系统和内存管理之间的接口。

  过程通讯

  进程通信支持提供进程之间的通信。 Linux支持多种进程间的通信机制,包括信号量、共享内存、管道等,这些机制可以辅助多个进程、多个资源的互斥访问、进程间的同步以及消息传递等。

  子系统之间的依赖关系

  Linux内核的五个组件之间的依赖关系如下:

  ·进程调度和内存管理的关系:这两个子系统是相互依赖的。 在多道程序环境中,程序运行必须创建一个进程,而创建进程时首先要做的就是将程序和数据加载到内存中。

  ·进程间通信与内存管理的关系:进程间通信子系统依靠内存管理来支持共享内存通信机制。 这种机制使得两个进程不仅可以拥有自己的私有空间,还可以访问公共的内存区域。

  ·虚拟文件系统与网络接口的关系:虚拟文件系统使用网络接口来支持网络文件系统(NFS),同时也使用内存管理来支持RAMDISK设备。

  ·内存管理和虚拟文件系统的关系:内存管理使用虚拟文件系统来支持交换。 交换进程(swapd)由调度程序定期调度。 这是内存管理依赖于进程调度的唯一原因。 当进程访问的内存映射被换出时,内存管理向文件系统发出请求,同时挂起当前正在运行的进程。

  除了这些依赖关系之外,内核中的所有子系统还依赖于一些公共资源。 这些资源包括所有子系统使用的例程,例如分配和释放内存空间的函数、打印警告或错误消息的函数以及系统提供的调试例程。

  linux内存管理图_linux内存布局图_linux内存管理源码剖析

评论区
头像