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

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寄存器保存到旧进程的 PCB
选择下一个妈妈决定让你去吃饭调度器从就绪队列选新进程
恢复现场吃完饭回来,根据书签继续做题将新进程 PCB 中的状态加载回 CPU寄存器
开始工作继续演算数学题CPU从保存的程序计数器(PC) 地址开始执行

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


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

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

http://www.xdnf.cn/news/1432567.html

相关文章:

  • 【Linux】进程信号
  • 第2.7节:多模态大模型之Midjourney
  • AI与低代码时代,自动化测试平台如何选型?主流工具详细对比及选型标准解析
  • github添加SSH密钥
  • vue2 跟 vue3 对比总结
  • 面向机器人系统的虚实迁移强化学习:从仿真训练到真实落地的技术突破
  • 重磅!PS2021 和企业微信 5.0 可直接运行,统信兼容引擎 V3.3.2 全面升级!
  • 提示词工程实战指南:5大技巧大幅提升LLM输出质量
  • 网络安全法合规视角下的安全运维体系建设:关键控制点与实施细节深度解析
  • 【论文阅读】DeepSeek-LV2:用于高级多模态理解的专家混合视觉语言模型
  • 【js】Promise.try VS try-catch
  • Spring Boot数据校验validation实战:写少一半代码,还更优雅!
  • 在线宠物用品|基于vue的在线宠物用品交易网站(源码+数据库+文档)
  • 硬件开发_基于物联网的自动售卖机系统
  • 联邦学习论文分享:GPT-FL: Generative Pre-Trained Model-AssistedFederated Learning
  • Apache 的安装及基本使用
  • MMORPG 游戏战斗系统架构
  • MATLAB矩阵及其运算(一)变量与常量
  • Python 中将 JSON 字符串转为对象的几种方法对比
  • 软件测试面试题【内附超详细面试宝典】
  • 【本地知识库问答系统】MaxKB搭建本地知识库问答系统
  • 低代码开发平台有哪些,中国十大低代码开发平台排名
  • 从零开始的云计算生活——第五十六天,临深履薄,kubernetes模块之etcd备份恢复和集群升级指南
  • Ruoyi-vue-plus-5.x第三篇Redis缓存与分布式技术:3.2 缓存注解与使用
  • 第2章:用户界面与基本监控
  • Ansible 循环、过滤器与判断逻辑
  • 小学一到六年级语文/英语/数学作业出题布置网站源码 支持生成PDF和打印
  • 基金交易量预测比赛_数据分析
  • MySQL 8.0 窗口函数详解:让数据分析更简单高效
  • 大数据毕业设计选题推荐-基于大数据的大学生就业因素数据分析系统-Spark-Hadoop-Bigdata