Linux - 进程切换

在这里插入图片描述


在这里插入图片描述


🎁个人主页:工藤新一¹

🔍系列专栏:C++面向对象(类和对象篇)

🌟心中的天空之城,终会照亮我前方的路

🎉欢迎大家点赞👍评论📝收藏⭐文章


文章目录

  • 进程切换 && 进程调渡
    • 一、补充概念-竞争、独立、并行、并发
      • 1.1 独立(Independent)
      • 1.2 并发(Concurrent)
      • 1.3 并行(Parallel)
      • 1.4并发 vs. 并行 的关键区别
      • 1.5 竞争(Race Condition)
      • 1.6 关系总结与图示
    • 二、进程切换
      • 2.1 什么是进程切换?如何理解?
        • **A. 死循环如何运行?**
        • **B. CPU,寄存器**
      • 2.2 进程切换如何来完成?

进程切换 && 进程调渡

一、补充概念-竞争、独立、并行、并发

1.1 独立(Independent)

  • 定义:指多个任务(进程或线程)之间没有任何关联,互不影响。一个任务的执行既不依赖另一个任务的输出,也不会共享任何资源(如数据、文件、内存等)。
  • 核心无共享,无交互
  • Linux 示例
    • 你电脑上的文本编辑器进程和后台播放音乐的进程,通常是独立的。它们各自处理自己的任务,一个崩溃了通常不会直接影响另一个。
    • 两个毫不相干的 shell 命令,例如 ls /homedate,它们就是独立的。
  • 比喻:两条平行的铁轨上行驶的火车,永不相交,互不干扰。

1.2 并发(Concurrent)

  • 定义:指系统具有处理多个任务的能力。这些任务在时间上是重叠的,即在一个时间段内,有多个任务都在推进。它不指定这些任务是否同时运行。
  • 核心重叠的时间段,有能力处理多任务。这是逻辑上的概念。
  • 与硬件的联系:并发可以在单核 CPU 上实现。操作系统通过快速的时间片轮转,在极短的时间间隔内切换执行不同的任务,从而让用户感觉所有任务在同时进行。
  • Linux 示例
    • 在单核 CPU 的电脑上,你一边用浏览器上网,一边用播放器听音乐。CPU 快速地在两个进程间切换,宏观上看起来它们是同时运行的,这就是并发。
    • 一个单核服务器同时处理多个来自客户端的网络请求。
  • 比喻:一个厨师同时照看一口锅里炖的汤、一口锅里炒的菜。他需要交替进行(搅拌汤、翻炒菜),在一顿饭的时间段内,两件事都在推进。

1.3 并行(Parallel)

  • 定义:指系统同时执行多个任务。在同一个时刻,有多个任务真正地在同时运行
  • 核心同一时刻,真正同时执行。这是物理上的概念。
  • 与硬件的联系:并行必须在多核 CPU、多个 CPU 或多台机器上才能实现。每个核心可以独立执行一个任务。
  • Linux 示例
    • 在多核 CPU 上,内核可以将不同的进程或线程调度到不同的核心上真正同时运行。
    • 使用 make -j4 编译大型项目,-j4 选项告诉 make 工具启动 4 个编译任务,它们可以在多个核心上并行运行,极大加快编译速度。
  • 比喻:多位厨师在同一厨房的不同灶台上同时做不同的菜。

1.4并发 vs. 并行 的关键区别

这是一个非常经典的面试题。

  • 并发是关于代码结构的,并行是关于执行的
  • 并发是问题,并行是解决方案。我们编写并发程序(如多线程程序)来解决问题,而硬件(多核CPU)提供并行执行的能力来加速这个并发程序。
  • 并发是逻辑上的同时发生,并行是物理上的同时发生
  • 并发的程序不一定能并行,但能并行的程序一定是并发的。一个设计不良的并发程序可能因为资源竞争而无法有效利用多核。

一句话总结并发是“同时”管理很多事情,并行是“同时”做很多事情;并行在任意 “时刻” 同时运行多个进程,并发在某 “时间段” 使多个进程同时推进

在这里插入图片描述


在这里插入图片描述


1.5 竞争(Race Condition)

  • 定义:这是一种错误状态,指多个并发/并行执行的进程或线程访问和操作共享资源(如全局变量、文件、内存) 时,最终的结果依赖于它们执行的具体时序。由于时序是不可预测的,导致程序的行为变得不确定,可能产生非预期的、错误的结果。

  • 核心结果的不确定性。这是一个需要避免的 Bug。

  • 产生条件

    1. 存在共享资源(数据)。
    2. 存在多个执行流(并发/并行)访问该资源。
    3. 至少有一个执行流是写操作
    4. 缺乏同步机制(如锁、信号量)来保护访问顺序。
  • Linux 示例

    // 全局共享变量
    int counter = 0;// 线程函数
    void *increment(void *arg) {for (int i = 0; i < 100000; i++) {counter++; // 这不是原子操作!}return NULL;
    }int main() {pthread_t thread1, thread2;pthread_create(&thread1, NULL, increment, NULL);pthread_create(&thread2, NULL, increment, NULL);pthread_join(thread1, NULL);pthread_join(thread2, NULL);printf("Final counter value: %d\n", counter); // 很可能不是 200000return 0;
    }
    

    counter++ 看起来是一条语句,但在汇编层面是“读-改-写”三步。两个线程可能同时读到了相同的值,然后加一,再写回,导致其中一次增加被覆盖。最终结果是一个随机数,这就是竞争。


1.6 关系总结与图示

特性独立并发并行竞争
核心思想互不干扰交替推进**(时间段)**同时执行**(时间点)**时序错误
依赖硬件单核即可必须多核无(但并行会加剧)
共享资源可能有可能有必须有
是否期望是(简化设计)是(提高效率)是(提高性能)否(必须避免)

它们之间的关系可以这样看:

  1. 你编写了一个 并发 的程序(多线程)来解决一个问题,期望它能利用多核特性 并行 执行以提高速度。
  2. 如果这些并发/并行的线程访问了 非独立 的(即共享的)数据,并且你没有做好同步保护,那么就会产生 竞争 条件,导致程序出错。
  3. 为了让并发程序正确运行,你必须通过同步机制(如互斥锁)将那些访问共享资源的 临界区 序列化,使其在逻辑上变回“独立”的片段,从而消除竞争。

• **竞争性:**系统进程数⽬众多,而 CPU资源只有少量,甚⾄1个,所以进程之间是具有竞争属性的。为 了⾼效完成任务,更合理竞争相关资源,便具有了优先级,权限…

• **独立性:**多进程运⾏,需要独享各种资源,多进程运⾏期间互不⼲扰

• **并行:**多个进程在多个 CPU下分别,同时进⾏运⾏,这称之为并⾏

• **并发:多个进程在单 CPU下采⽤“进程切换”**的方式,在⼀段时间之内,让多个进程都得以推进,这种模式称之为并发


二、进程切换

2.1 什么是进程切换?如何理解?

核心定义:
进程切换(Process Switching),也称为上下文切换(Context Switching),是指操作系统将CPU从一个正在运行的进程夺回,并分配给另一个就绪的进程,同时保存和恢复相应进程的状态的过程。

通俗理解:
想象一下你是一个学生**(CPU),正在做数学作业(进程A)。突然,你妈妈(OS)**说:“别做数学了,先来吃饭!(中断)” 于是你(CPU)需要:

  1. 停下来:放下数学笔。
  2. 做标记:用一个书签(保存上下文)精确地记录下你做到哪一题、哪一步,草稿纸上的关键数字是什么。(记录/保留当前痕迹)
  3. 换任务:起身去餐桌吃饭(进程B)。
  4. 吃完饭回来:你根据书签上的记录(恢复上下文),找到刚才的步骤和数字,继续做数学题。

这个过程就是“进程切换”。操作系统就是那个妈妈,它负责在你(CPU)不同的任务(进程)之间进行调度,而书签就是进程的上下文。(作业中的内容 — 进程运行时的临时数据,CPU寄存器中的内容


在这里插入图片描述


为什么需要它?

  • 实现多任务:让单个CPU也能“同时”运行多个程序(如边听歌边上网),靠的就是在进程间极速切换(每秒上百次),人类无法感知。
  • 提高CPU利用率:当一个进程等待慢速操作时(如读磁盘、等网络),CPU不能闲着,立刻切换到其他可以运行的进程。

A. 死循环如何运行?
  • a. 一旦进程占有CPU,会一直把自己的代码跑完吗?不会!

(除非进程的代码数据短)OS 会为每一个进程分配 时间片(给进程1ms时间让进程运行,若进程未运行结束,就将进程从 CPU上剥/抽离,使进程在运行队列中重新排队)。因此,任何进程对于 CPU资源的运用都是临时性的,这样就不会出现一个进程死占 CPU的情况

  • b. 死循环进程不会打死系统,因为其不会一直都占有 CPU!

B. CPU,寄存器

在这里插入图片描述


2.2 进程切换如何来完成?

进程切换是操作系统内核最核心的工作之一,它完全在内核态下执行。整个过程可以分解为以下几个关键步骤,主要由 schedule() 函数实现:

触发时机(妈妈喊你吃饭的原因):

  • 主动让出:进程自己调用 sleep(), exit() 等系统调用。
  • 时钟中断:一个硬件定时器每隔几毫秒发出一次中断,强制夺回CPU控制权,让调度器有机会决定是否切换。这是最常见的原因
  • 等待资源:进程需要等待磁盘I/O、网络包、锁等资源,自己进入阻塞状态。
  • 被更高优先级进程抢占:一个更高优先级的进程变为就绪状态。

切换步骤(妈妈让你换任务的具体动作):

  1. 中断当前进程:时钟中断或系统调用触发,CPU硬件自动将用户态的上下文(如程序计数器PC、栈指针SP等)保存到当前进程的内核栈中,并切换到内核态。
  2. 执行内核中断处理程序:CPU开始执行操作系统预设的中断处理代码。
  3. 决定是否切换:中断处理程序调用调度器 schedule()。调度器检查是否需要切换(例如当前进程的时间片用完了)。
  4. 保存当前进程上下文:如果需要切换,内核将当前进程的完整硬件上下文(所有CPU寄存器的值:通用寄存器、状态寄存器、程序计数器等)保存到它的进程控制块(PCB) 中。
    • PCB(task_struct:Linux中每个进程都有一个巨大的数据结构(struct task_struct),它是进程的“身份证”和“病历本”,记录了一切信息,其中就包括保存上下文的字段。
  5. 选择下一个进程:调度器从就绪队列中,根据某种算法(如CFS完全公平调度器)选出下一个最值得运行的进程。
  6. 切换地址空间:切换 CR3寄存器(在x86架构上)。这个寄存器指向当前进程的页目录,切换它就等于切换了整个虚拟内存空间。这是进程隔离的关键,进程A无法访问进程B的内存。
  7. 恢复下一个进程的上下文:内核将下一个进程的PCB中保存的寄存器值全部加载到CPU的各个寄存器中。这包括恢复它的程序计数器(PC),这意味着CPU接下来要执行的指令地址就变成了这个新进程的。
  8. 切换内核栈:将当前 CPU的栈指针(SP)指向新进程的内核栈。因为每个进程都有自己的内核栈,用于执行系统调用和中断处理。
  9. 返回用户态:上下文恢复完成后,中断处理程序执行返回指令。CPU硬件自动从新进程的内核栈中恢复用户态的上下文(PC, SP等),并切换到用户态。
  10. 开始运行新进程:由于PC寄存器指向的是新进程被中断时的指令地址,CPU便开始执行新进程,仿佛它从未停止过。

在这里插入图片描述
所以只要是在CPU内的寄存器(用户级别)我们可以观测到的寄存器都需要被保存


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


步骤类比(学生做作业)技术对应
触发妈妈喊“先别做了,来吃饭”时钟中断系统调用
保存现场用书签标记做到哪一题、哪一步CPU寄存器保存到旧进程的 PCB
选择下一个妈妈决定让你去吃饭调度器从就绪队列选新进程
恢复现场吃完饭回来,根据书签继续做题将新进程 PCB 中的状态加载回 CPU寄存器
开始工作继续演算数学题CPU从保存的程序计数器(PC) 地址开始执行

记住核心:进程切换的本质是 保存状态 -> 换人 -> (记录上一次痕迹)恢复状态。这个过程由硬件中断触发,由操作系统内核借助 进程控制块(PCB) 精密完成,是实现一切多任务魔力的基石


在这里插入图片描述


在这里插入图片描述
🌟 各位看官好我是工藤新一¹呀~

🌈 愿各位心中所想,终有所致!

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

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

相关文章

机器算法(五)模型选择与调优

一 交叉验证1 保留交叉验证HoldOutholdOut Cross-validation(Train-Test Split)在这种交叉验证技术中&#xff0c;整个技术集被随机划分为训练集和验证集。根据经验法则&#xff0c;整个数据集的近70%被用作训练集&#xff0c;其余30%被用作验证集&#xff0c;也就是最常使用的…

Ubuntu 服务器实战:Docker 部署 Nextcloud+ZeroTier,打造可远程访问的个人云

本次部署基于 Ubuntu 系统&#xff08;桌面版 / Server 版通用&#xff0c;核心操作一致&#xff09;&#xff0c;硬件配置参考如下&#xff0c;低配置主机可顺畅运行&#xff1a; ubuntu服务器配置如下 硬件类型具体型号/参数CPUIntel Core i3-6100T内存条8GB&#xff08;DD…

移动硬盘删除东西后,没有释放空间

请按照以下步骤&#xff0c;从最简单、最常见的原因开始排查和解决&#xff1a;主要原因和解决方案1. 检查操作系统回收站 (最常见原因&#xff01;)这是最容易被忽略的一点。当您直接在外接移动硬盘上删除文件时&#xff0c;文件并不会直接消失&#xff0c;而是被移到了该移动…

spring boot驴友结伴游网站的设计与实现(代码+数据库+LW)

摘要 本文介绍了基于Spring Boot框架开发的驴友结伴游网站的设计与实现。该网站旨在为旅行爱好者提供一个便捷的平台&#xff0c;使他们能够轻松地寻找伙伴、预定酒店、参与活动以及分享旅行经历。系统主要分为两大模块&#xff1a;用户模块和管理员模块。用户可以通过注册账号…

人机之间的强交互与弱交互

人机交互不是简单的人机&#xff0c;其本质是人机环境系统的交互。在这个系统中&#xff0c;人和机器不是孤立的存在&#xff0c;而是在特定环境下相互影响、相互作用的一部分。人机之间的强交互与弱交互可以从以下几个方面来理解&#xff1a;1、人机强交互通常是指人与机器之间…

OpenCV 基础知识总结

学习网站 https://zhuanlan.zhihu.com/p/483604320 命名空间 using namespace cv; Mat 作用 创建图像&#xff08;矩阵&#xff09; 格式 Mat image; //创建一个空图像image&#xff0c;大小为0 Mat image(100,100,CV_8U); //指定矩阵大小&#xff08;矩阵行数/列数&#xff09…

C#基础(⑦user32.dll)

我们来详细学习如何使用 user32.dll&#xff0c;它是 Windows 系统中负责用户界面交互的核心 DLL&#xff0c;包含窗口管理、消息处理、键盘鼠标输入等功能。下面从基础到进阶&#xff0c;一步一步教你调用其中的常用函数。在 C# 中调用 user32.dll 需要使用 DllImport 特性&am…

Markdown格式.md文件的编辑预览使用

推荐工具Visual Studio Code (VS Code) - 强烈推荐特点&#xff1a;微软出品&#xff0c;免费、开源、跨平台&#xff08;Windows, macOS, Linux&#xff09;。拥有海量插件市场。编辑体验&#xff1a;安装 Markdown All in One 等插件后&#xff0c;可以获得语法高亮、实时预览…

TypeScript:unknown 类型

作为前端开发工程师&#xff0c;在 TypeScript 中使用 unknown 类型是提升类型安全的关键实践。下面我会结合实际开发场景详细讲解其特性和价值。unknown 核心特性1.类型安全的顶级类型与 any 类似&#xff0c;可接受任何类型的赋值&#xff1a;let userInput: unknown; userIn…

2025 批量下载hasmart所有知乎回答,文章和想法,导出txt,html和pdf

之前分享过文章2025 一键批量下载备份知乎回答/文章/想法/专栏/视频/收藏夹&#xff0c;导出txt&#xff0c;html和 pdf &#xff0c;今天继续下载hasmart这个号的所有知乎回答 下载的知乎回答目录&#xff0c;包含发布时间和标题&#xff0c;点击可跳转对应回答。 2019年发布…

mapbox高阶,结合threejs(threebox)添加管道,实现管道流动效果

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言 1.1 ☘️mapboxgl.Map 地图对象 1.2 ☘️mapboxgl.Map style属性 1.3 ☘️threebox add加载网格对象 二、🍀…

语音识别后处理——如何语音断句加上标点、顺滑、ITN等

基本流程 基于cpu的计算&#xff1a; 前往intel官网下载libmkl相关的库&#xff1a;libmkl_core.a、libmkl_gf_lp64.a、libmkl_sequential.a # 静默安装 ./intel-onemkl-2025.2.0.629_offline.sh -a -s --eula accept默认安装目录&#xff1a;/opt/intel/oneapi libmkl相关的…

[吾爱出品] 图片转换王 v1.01 - 多格式支持 / 支持pds、Ai格式

[吾爱出品] 图片转换王 多格式支持 链接&#xff1a;https://pan.xunlei.com/s/VOZ81aeES9JDqlcvXPKYlxwqA1?pwdni9b# 图片转换王」是一款专为设计师、自媒体从业者及普通用户打造的专业图片格式转换工具&#xff0c;秉持绿色便携理念&#xff0c;无需繁琐安装步骤&#xf…

GitLab 18.3 正式发布,更新多项 DevOps、CI/CD 功能【一】

沿袭我们的月度发布传统&#xff0c;极狐GitLab 发布了 18.3 版本&#xff0c;该版本带来了通过直接转移进行迁移、CI/CD 作业令牌的细粒度权限控制、自定义管理员角色、Kubernetes 1.33 支持、通过 API 让流水线执行策略访问 CI/CD 配置等几十个重点功能的改进。下面是对部分重…

【macOS】垃圾箱中文件无法清理的--特殊方法

【macOS】垃圾箱中文件无法清理的特殊方法直接拖拽到 Beyond Compare App中&#xff0c;删除时&#xff0c;选择以下选项即可彻底删除。1.在macOS桌面&#xff0c;将垃圾箱打开2.将垃圾文件和文件夹&#xff0c;拖拽到Beyond Compare界面3.选中待删除的文件和文件夹如上图。4.鼠…

Python UV 管理如何使用镜像源安装 Python

uv python install [版本号] --mirrorhttps://github.com/astral-sh/python-build-standalone/releases/download/这是默认情况下 uv python 安装命令&#xff0c;命令会找到 astral 公司在 Github 上的存储库&#xff0c;然后进行下载。我们只需要为 mirror 增加任意 Github 镜…

SPI片选踩坑实录(硬件片选和软件片选)

SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;的片选信号&#xff08;Chip Select&#xff0c;简称 CS 或 SS&#xff0c;即 Slave Select&#xff09;是 SPI 通信中用于选择从设备的关键控制信号&#xff0c;其作用是在多从设备的 SPI 总线…

从理论到RTL,实战实现高可靠ECC校验(附完整开源代码/脚本)(3) RTL实现实战

第二部分&#xff1a;ECC &#xff08;30&#xff0c; 24&#xff09;RTL实现实战 - 精雕细琢的硬件卫士 理论是基石&#xff0c;实现是关键。本部分将 手把手构建参数化、可综合、高可靠的ECC编解码器 。本部分将以MIPI 协议中Packet Header 用到的ECC(30&#xff0c;24) 为例…

揭密设计模式:像搭乐高一样构建功能的装饰器模式

揭密设计模式&#xff1a;像搭乐高一样构建功能的装饰器模式 在软件开发中&#xff0c;我们常常会遇到一个问题&#xff1a;如何给一个对象动态地添加新功能&#xff0c;同时又不想修改它的代码&#xff1f;如果直接在原有类上修修补补&#xff0c;代码会变得臃肿复杂&#xff…

【Vue】前端 vue2项目搭建入门级(二)

本文不同于【Vue】前端 vue2项目搭建入门级&#xff08;一&#xff09;&#xff0c;本文创建vue2项目方式是一键创建vue2 项目&#xff0c;不需要自己配置。1.cmd进入根目录&#xff0c;输入vue create project&#xff08;vue create 项目名&#xff09;创建一个project的项目…