当前位置: 首页 > news >正文

深入分析Linux上下文与上下文切换

Linux 进程运行空间与特权等级

在 Linux 操作系统中,进程的运行空间被划分为内核空间和用户空间,这种划分是为了保护系统的稳定性和安全性。这两个空间对应着 CPU 的特权等级,分别为:

  • Ring 0(内核态)
  • Ring 3(用户态)
  • 本文将深入介绍这两个空间的概念、特权等级的含义以及它们之间的切换机制。

内核空间与用户空间

内核空间

内核空间是操作系统内核运行的区域,拥有最高的特权等级。在内核空间中,操作系统可以执行任意指令,访问所有硬件和内存资源。这包括对系统硬件、设备驱动程序和核心数据结构的完全访问。内核空间通常包含了操作系统的内核代码和数据结构。

用户空间

用户空间是供用户程序执行的区域,拥有较低的特权等级。在用户空间中,程序只能执行受限的指令,且对硬件资源的直接访问受到限制。用户空间包含了用户应用程序的代码和数据,以及一些共享库和用户环境的运行时信息。

CPU 特权等级

CPU 特权等级用于区分不同程序对计算机系统资源的访问权限。在 x86 架构中,特权等级被分为四个环,分别是:

  • Ring 0
  • Ring 3

Ring 0 拥有最高特权,而 Ring 3 拥有最低特权。

1. Ring 0 - 内核态

    Ring 0 是最高特权等级,对应内核空间。在 Ring 0 中,操作系统内核运行,可以执行任意指令,访问系统的全部资源。内核态下运行的代码可以执行特权指令,例如修改全局描述符表(GDT)和局部描述符表(LDT),以及执行 I/O 操作。

2. Ring 3 - 用户态

    Ring 3 是最低特权等级,对应用户空间。在 Ring 3 中,运行用户应用程序,程序只能执行非特权指令,访问受限资源。用户态下运行的代码无法直接执行一些特权指令,例如修改 GDT 和 LDT。必须通过系统调用陷入到内核中,才能访问这些特权资源。

上下文

Linux 是一个多任务操作系统,支持远远大于cpu数量的任务并行运行,但是从底层上看其实这些任务也不是同时运行,而是操作系统在非常短的时间内把CPU轮流分配给这些任务,这样在表象看起来像是多任务同时运行一样。

因为这些任务实际上是轮流使用cpu,所以在任务运行之前就得有地方记录这些任务的运行信息(需要加载什么信息,在哪里开始运行等)--CPU 寄存器和程序计数器。

在 Linux 操作系统中,当操作系统进行进程上下文切换时,通常会保存和恢复CPU 寄存器的状态,以及程序计数器的值。这确保了在切换回进程时,它能够继续执行先前被中断的位置。这是操作系统实现多任务和多进程并发执行的基本机制之一。

CPU 寄存器

  • 含义: CPU 寄存器是一组用于暂时存储数据的小型存储区域,直接嵌入在 CPU 中。寄存器在计算机中起到非常关键的作用,用于存储临时数据、地址、状态等信息。

  • 关联进程资源: 寄存器包括通用寄存器、特殊用途寄存器等。在进程上下文切换时,通用寄存器的值通常会被保存到进程的上下文中,以便在切换回该进程时能够恢复到之前的状态。

程序计数器(Program Counter,PC)

  • 含义: 程序计数器是一种特殊的寄存器,用于存储当前正在执行的指令的地址,即程序的下一条指令的地址。

  • 关联进程位置: 程序计数器的值指示了进程在内存中的特定位置,表示即将执行的指令的地址。在进程执行期间,计算机会不断更新程序计数器的值,使其指向下一条要执行的指令的地址。

CPU 寄存器和程序计数器。都是 CPU 在运行任何任务前,必须的依赖环境,因此也被叫做 CPU 上下文。

一句话总结上下文:

    在每个任务运行前,cpu需要知道任务是从哪儿运行的,然后从哪儿开始的,也就是说,需要系统给它设置好 CPU寄存器和程序计数器, cpu的寄存器是,cpu内置的容量小,但是速度极快的内存,而程序计数器,则是用来存储正在执行的指令位置,或者即将执行的吓一跳指令位置。他们是cpu在运行任何任务前,都必须依赖的环境(包括寄存器状态、内存映射、打开的文件、进程优先级等),因此也被叫做CPU上下文。

一句话总结上下文切换:

    就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。

上下文切换

上下文切换是指操作系统在多任务环境下,从一个任务切换到另一个任务时保存和恢复这些上下文信息的过程。在 Linux 系统中,上下文和上下文切换是操作系统中关键的概念,对于系统性能和多任务处理有着重要的影响。

在多任务操作系统中,CPU 上下文切换是实现并发执行的关键机制。根据任务的不同,可以把上下文切换可以分成三种不同的上下文切换场景:进程上下文切换、线程上下文切换以及中断上下文切换。我们将从底层原理出发,详细介绍每种场景的具体实现和影响因素。

进程上下文切换

进程的上下文切换

    进程上下文切换是指从一个进程切换到另一个进程。它发生在多任务系统中,由调度器负责决定哪个进程获得 CPU 时间。上下文切换的开销包括保存当前进程的上下文、加载新进程的上下文以及刷新内存映射等。

系统调用的上下文切换

    在一开始介绍进程的运行空间与系统等级的时候,进程在从用户态到内核态的转变涉及系统调用,这里的系统调用也涉及上下文切换。系统调用是用户程序请求内核执行特权操作的方式,例如打开、读取或关闭文件。当进行文件内容查看等操作时,需要多次系统调用完成。每次系统调用都引发了 CPU 上下文的切换。

具体过程如下:

  1. 保存用户态: 在系统调用开始时,CPU 寄存器里保存着用户态的指令位置,需要先保存这些信息以便后续恢复。

  2. 进入内核态: 为了执行内核态代码,CPU 寄存器需要更新为内核态指令的新位置。

  3. 执行内核任务: 此时,CPU 进入内核态并执行相应的内核任务,完成系统调用的操作。

  4. 恢复用户态: 系统调用结束后,CPU 寄存器需要恢复原来保存的用户态,然后切换回用户空间,继续运行进程。

一次系统调用的过程实际上发生了两次 CPU 上下文切换。

虽然系统调用过程中不涉及虚拟内存等用户态资源的切换,也不会切换进程,但实际上,CPU 的上下文切换是无法避免的。因此,系统调用过程中的上下文切换通常被称为特权模式切换,而非上下文切换。

进程上下文切换与系统调用的区别

进程上下文切换与系统调用有明显区别:

  1. 上下文内容:

    进程上下文切换包括了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的状态。

    系统调用时,只保存和恢复了 CPU 寄存器和用户态的状态。

  2. 切换对象:

    进程上下文切换是在不同进程之间进行的

    系统调用过程中一直是同一个进程在运行

  3. 过程复杂度:

    进程上下文切换相对于系统调用更为复杂。它需要保存当前进程的内核状态和 CPU 寄存器之前,还需要保存该进程的虚拟内存、栈等;加载下一进程的内核态后,还需要刷新进程的虚拟内存和用户栈。

进程上下文切换的开销

上下文切换的过程并非“免费”,它需要内核在 CPU 上运行来完成。根据Tsuna的实验数据,每次上下文切换都需要几十纳秒到数微秒的 CPU 时间。在进程上下文切换次数较多的情况下,容易导致 CPU 时间主要花费在资源的保存和恢复上,而非真正的进程执行。

进程调度与上下文切换的时机

在 Linux 系统中,进程的调度并不仅仅发生在进程执行完终止的时候。我们来逐一梳理几个触发进程调度的场景,以加深对进程调度机制的理解。

1. 时间片耗尽
时机:
  • 当前运行进程的时间片耗尽。

为了保证所有进程能够得到公平调度,CPU 时间被划分为一段段的时间片,这些时间片轮流分配给各个进程。当某个进程的时间片耗尽时,系统会挂起该进程,并切换到等待 CPU 的其他进程运行。

2. 系统资源不足
时机:
  • 进程等待某些系统资源(如内存)。

在系统资源不足的情况下(例如内存不足),进程需要等待资源满足才能继续运行。此时,该进程会被挂起,并由系统调度其他等待 CPU 的进程运行。

3. 睡眠函数
时机:
  • 进程主动调用睡眠函数(如 sleep)。

通过睡眠函数(如 sleep)等方式,进程可以主动挂起自己,等待一定的时间后再次被调度运行。

  1. 进程进入睡眠状态,不再占用 CPU 资源。

  2. 睡眠时间结束或被唤醒后,进程重新被调度运行。

4. 优先级更高的进程
时机:
  • 高优先级进程就绪并准备运行。

当有优先级更高的进程就绪时,为了确保高优先级进程能够及时运行,当前进程会被挂起,系统调度高优先级进程运行。

  1. 低优先级进程被挂起。

  2. 高优先级进程获得 CPU 控制权,运行相应任务。

  3. 执行完任务后,系统可能重新调度低优先级进程。

5. 硬件中断
时机:
  • 硬件设备产生中断。

发生硬件中断时,CPU 上正在执行的进程会被中断挂起,转而执行内核中的中断服务程序。一旦中断处理完毕,原先的进程可能会被重新调度运行。

  1. 当前进程被中断挂起。

  2. 中断服务程序执行。

  3. 中断处理完成后,可能重新调度原先的进程继续执行。

线程上下文切换

    线程上下文切换与进程上下文切换类似,但开销更小。因为线程共享相同的地址空间,切换时无需刷新内存映射。线程上下文切换通常发生在同一进程内的不同线程之间。

    线程(Thread)和进程(Process)是操作系统中用于执行程序的两个基本概念,在开始分析之前,我们先了解下线程与进程:线程是调度的基本单位,而进程则是资源拥有的基本单位

  1. 任务调度:

    • 线程是操作系统进行任务调度的基本单位。内核可以调度多个线程在同一进程中并发执行,充分利用多核处理器的性能。

    • 进程是一个独立的执行环境,它包含至少一个线程。但在内核的任务调度中,调度的对象是线程,而非整个进程。

  2. 资源拥有:

    • 进程是独立的资源拥有者,拥有独立的地址空间、文件描述符等。不同进程之间的资源是相互独立的。

    • 线程共享相同进程的资源,包括虚拟内存、文件描述符等。线程间的通信相对简单,因为它们共享相同的地址空间。

    • 线程也有自己的私有数据,比如栈和寄存器等。

  3. 调度效率:

    • 由于线程共享相同的资源,线程的创建、销毁和切换开销相对较小,调度效率较高。

    • 进程的独立性导致了较大的创建、销毁和切换开销,因为这涉及到整个地址空间的切换。

  4. 错误影响范围:

    • 一个线程的错误可能影响整个进程,因为它们共享相同的资源。这需要更加谨慎的编程和调试。

    • 进程的独立性使得一个进程的错误不太可能直接影响其他进程,提高了系统的稳定性。

线程上下文切换 可以分为两种情况

  1. 前后线程属于不同的进程。因为资源不共享,所以上下文切换的过程与进程上下文切换时一样的。

  2. 如果前后两个线程属于一个进程。因为虚拟内存是共享的,所以切换的时候 虚拟内存等资源是不用动的,只需要切换不同线程自己拥有的私有数据,寄存器等不共享的数据。

中断上下文切换

中断上下文切换是由硬件中断或软件中断触发的。当中断发生时,操作系统会保存当前进程或线程的上下文,然后转入中断服务例程执行。执行完中断服务例程后,操作系统会恢复之前保存的上下文,继续执行被中断的进程或线程。

中断上下文切换与进程上下文切换有着明显的区别。中断上下文切换并不涉及到进程的用户态,因此在中断过程中打断了一个正处在用户态的进程时,不需要保存和恢复这个进程的虚拟内存、全局变量等用户态资源。相比之下,中断上下文只包括内核态中断服务程序执行所必需的状态,主要包括 CPU 寄存器、内核堆栈、硬件中断参数等。

中断上下文切换的特点:

  1. 内核态执行:

    • 中断上下文切换是在内核态下执行的,与用户态进程无关。因此,不需要保存和恢复用户态的资源。

  2. 资源限定:

    • 中断上下文主要关注于提供中断服务所需的最少资源,包括 CPU 寄存器、内核堆栈、硬件中断参数等。

    • 与进程上下文切换相比,中断上下文切换的资源范围较为有限,着重于满足中断处理的基本需求。

  3. 无需虚拟内存切换:

    • 由于中断上下文不牵涉用户态,因此无需切换虚拟内存。不同进程的虚拟内存空间在中断上下文中并不影响。

  4. 快速执行:

    • 中断上下文切换的目标是尽快响应硬件中断,因此切换过程相对迅速。

    • 这与进程上下文切换不同,后者可能涉及到更多的资源保存和恢复,因而相对较慢。

中断上下文切换的设计目标是最小化对系统性能的影响,专注于提供必要的执行环境以迅速处理硬件中断。这种机制使得操作系统能够高效地响应外部事件,保证系统的可靠性和实时性。

总结

上下文和上下文切换是操作系统中的关键概念,直接影响系统的性能和响应能力。了解上下文的概念以及上下文切换的过程有助于理解操作系统的工作原理,并能够优化程序以提高系统的性能和效率。在设计和开发多任务应用程序时,合理处理上下文切换是至关重要的。

相关文章:

深入分析Linux上下文与上下文切换

Linux 进程运行空间与特权等级 在 Linux 操作系统中,进程的运行空间被划分为内核空间和用户空间,这种划分是为了保护系统的稳定性和安全性。这两个空间对应着 CPU 的特权等级,分别为: Ring 0(内核态)Ring…...

Docker快速上手及常用命令速查

Docker快速上手 安装 在ubuntu上安装docker: sudo apt-get install docker docker -v #查看版本在centos7上安装docker:(docker在YUM源的Extras仓库中) yum install docker systemctl start dockerdocker常用命令速查 #查看docker信息 docker info #查看本地镜…...

学习笔记:解决拖延

1 解决拖延、减轻压力的关键心态和方法 1.1 要点梳理 拖延是因为自己一直在逃避,重点是要有效突破逃避圈,进入学习圈,扩展成长圈。 毒蛇曲线(见思维导图)中越是临近截止期限,拖延的焦虑越上升&#xff0…...

第一个Swift程序

要创建第一个Swift项目,请按照以下步骤操作: 打开Xcode。如果您没有安装Xcode,可以在App Store中下载并安装它。在Xcode的欢迎界面上,选择“Create a new Xcode project”(创建新Xcode项目)。在模板选择界面上,选择“App”(应用程序)。在应用模板选择界面上,选择“Si…...

Anthropic Claude 3 加入亚马逊云科技 AI“全家桶”

编辑 | 宋慧 出品 | CSDN AIGC 每天都有新动态发生。最新的消息是亚马逊在 3 月底完成了对 Anthropic 的 40 亿美元投资(也是亚马逊 30 年来最大一笔外部投资),以及 GPT-4 最强对手的 Anthropic Claude 3 已经在亚马逊云科技 Amazon Bedrock…...

学习基于pytorch的VGG图像分类 day3

注:本系列博客在于汇总CSDN的精华帖,类似自用笔记,不做学习交流,方便以后的复习回顾,博文中的引用都注明出处,并点赞收藏原博主. 目录 VGG模型训练 1.导入必要的库 2.主函数部分 2.1使用cpu或gpu 2.2对数据…...

Spring Boot统一功能处理之拦截器

本篇主要介绍Spring Boot的统一功能处理中的拦截器。 目录 一、拦截器的基本使用 二、拦截器实操 三、浅尝源码 初始化DispatcherServerlet 处理请求(doDispatch) 四、适配器模式 一、拦截器的基本使用 在一般的学校或者社区门口,通常会安排几个…...

stm32之基本定时器的使用

在上文我们使用到了HAL库的自带的延时函数,HAL_Delay();我们来看一下函数的原型 __weak void HAL_Delay(uint32_t Delay) {uint32_t tickstart HAL_GetTick();uint32_t wait Delay;/* Add a freq to guarantee minimum wait */…...

单片机为什么还在用C语言编程?

单片机产品的成本是非常敏感的。因此对于单片机开发来说,最重要的是在极其有限的ROM和RAM中实现最多产品的功能。或者反过来说,实现相同的产品功能,所需要的ROM和RAM越小越好,在开始前我有一些资料,是我根据网友给的问…...

IO流的基础详解

文件【1】File类: 封装文件/目录的各种信息,对目录/文件进行操作,但是我们不可以获取到文件/目录中的内容。 【2】引入:IO流: I/O : Input/Output的缩写,用于处理设备之间的数据的传输。 【3】…...

实战攻防 | 记一次项目上的任意文件下载

1、开局 开局一个弱口令,正常来讲我们一般是弱口令或者sql,或者未授权 那么这次运气比较好,直接弱口令进去了 直接访问看看有没有功能点,正常做测试我们一定要先找功能点 发现一个文件上传点,不过老规矩,还…...

熔断之神:探寻Hystrix的秘密与实践指南

引言: 在微服务架构中,服务之间的依赖复杂且难以控制,容灾机制成为确保系统稳定性的重要手段。Hystrix作为Netflix开源的断路器实现,提供了一系列强健的容错功能。 Hystrix的核心概念与作用: Hystrix是一个由Netflix开…...

Web功能测试测试点总结!

web测试就是基于BS架构的软件产品的测试,通俗点来说就是web网站的测试。 一 、界面检查 当我们进入一个页面时,首先应该检查title,页面排版(即页面的展示),而不是马上进入字段校验页面面包屑导航是否正确当前位置是否可见 您的位…...

关于vue3的简单学习

Vue 3 简介 Vue 3 是一个流行的开源Java框架,用于构建用户界面和单页面应用。它带来了许多新特性和改进,包括更好的性能、更小的打包大小、更好的Type支持、全新的组合式 API,以及一些新的内置组件。 一. Vue 3 的新特性 Vue 3引入了许多新…...

windows server 2019 -DNS服务器搭建

前面是有关DNS的相关理论知识,懂了的可以直接跳到第五点。 说明一下:作为服务器ip最好固定下来,以DNS服务器为例子,如果客户机的填写DNS信息的之后,服务器的ip如果变动了的话,客户机都得跟着改&#xff0c…...

使用 XCTest 进行 iOS UI 自动化测试

使用 XCTest 进行 iOS UI 自动化测试是一种有效的方法,可以帮助你验证应用界面的行为和功能。以下是使用 XCTest 进行 iOS UI 自动化测试的基本步骤: 设置项目: 确保你的 Xcode 项目已经包含了 XCTest 测试目标。在测试目标中创建一个新的测试类&#xf…...

【Python】FANUC机器人OPC UA通信并记录数据

目录 引言机器人仿真环境准备代码实现1. 导入库2. 设置参数3. 日志配置4. OPC UA通信5. 备份旧CSV文件6. 主函数 总结 引言 OPC UA(Open Platform Communications Unified Architecture)是一种跨平台的、开放的数据交换标准,常用于工业自动化…...

Linux 中断处理

一、基本概念 1、中断及中断上下文 中断是一种由硬件设备产生的信号,不同设备产生的中断通过中断号来区分。CPU在接收到中断信号后,根据中断号执行对应的中断处理程序(Interrupt Service Routine) 内核对异常和中断的处理类似&a…...

人大金昌netcore适配,调用oracle模式下存储过程\包,返回参数游标

using KdbndpConnection conn new KdbndpConnection("Host192.168.133.221;Port54321;Databasedb1;Poolingtrue;User IDsystem;Password123");conn.Open();//存储过程调用也是类似using var cmd conn.CreateCommand();cmd.CommandText "模式.包名称.存储过程…...

pandas常用的一些操作

EXCLE操作 读取Excel data1 pd.read_excel(excle_dir) 读Excel取跳过前几行: data1 pd.read_excel(excle_dir,skiprows1) 获取总行数 data1.shape[0] 获取总列数 data1.shape[1] 指定某列数据类型 data1 pd.read_excel("C:数据导入.xlsx",dtype…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时,需要使用外部低速晶振...

全面解析数据库:从基础概念到前沿应用​

在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...

数据库正常,但后端收不到数据原因及解决

从代码和日志来看,后端SQL查询确实返回了数据,但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离,并且ai辅助开发的时候,很容易出现前后端变量名不一致情况,还不报错,只是单…...

小智AI+MCP

什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析:AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github:https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...

【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录

#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...

OpenGL-什么是软OpenGL/软渲染/软光栅?

‌软OpenGL(Software OpenGL)‌或者软渲染指完全通过CPU模拟实现的OpenGL渲染方式(包括几何处理、光栅化、着色等),不依赖GPU硬件加速。这种模式通常性能较低,但兼容性极强,常用于不支持硬件加速…...