【操作系统OS】学习笔记:第二章 进程与线程 (上)【哈工大李治军老师】

news2024/12/28 5:07:55

基于本人观看学习 哈工大李治军老师主讲的操作系统课程 所做的笔记,仅进行交流分享

特此鸣谢李治军老师,操作系统的神作!

如果本篇笔记帮助到了你,还请点赞 关注 支持一下 ♡>𖥦<)!!

主页专栏有更多,如有疑问欢迎大家指正讨论,共同进步!

给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ

第二章 进程与线程 (上)


更多操作系统笔记:【哈工大李治军老师】操作系统笔记专栏汇总

如果有需要markdown或者PDF可以私信我,可以在此基础上自己添加补充笔记(●’◡’●)


目录:

  • 第二章 进程与线程 (上)
  • 课程链接:
  • 一、CPU管理的直观想法
    • 1.CPU的工作原理
    • 2.多道程序,交替执行
    • 3.如何做到并发?
    • 4.进程
  • 二、多进程图像
    • 1.多进程图像是操作系统的核心图像
    • 2.多进程如何组织?
    • 3.进程状态图:
    • 4.多进程如何交替?
    • 5.多进程如何影响?
    • 6.多进程如何合作?
  • 三、用户级线程
    • 1.资源切换(引出线程概念)
      • 多个执行序列+一个地址空间是否实用?
    • 2.线程切换
      • 从一个栈到两个栈
    • 3.用户级线程与核心级线程
  • 四、内核级线程
    • 1.用户栈和内核栈之间的关联
    • 2.开始内核中的切换:switch_to
  • 五、内核级线程实现
    • 1.int 0x80 fork( )
    • 2.切换五段论中的中断入口和出口
    • 3.switch to
    • 4.ThreadCreate
      • copy_process的细节:创建栈
      • copy_process的细节:执行前准备
    • 5.如何执行我们想要的代码?
    • 内核级线程总结
  • 六、操作系统的“树”(知识串讲总结)


课程链接:

b站: 【哈工大】操作系统 李治军(全32讲)

大学MOOC:大学慕课—操作系统—主讲:哈工大李治军



一、CPU管理的直观想法

操作系统在管理CPU时引入了一个多进程图像,通过多进程图像操作系统管理CPU

多进程图像是操作系统的核心图像。

1.CPU的工作原理

  1. 取指:CPU 从内存中读取指令,并解析指令中的操作码和操作数等信息。
  2. 执行:根据指令中的操作码和操作数,CPU 进行相应的逻辑或算术运算,并将结果保存到寄存器或内存中。
  3. 写回:如果结果需要保存到内存中,则将结果写入内存,或者将结果保存到寄存器中供后续指令使用。
  4. 重复:不断重复上述步骤,直到程序执行结束。
  1. 取指:CPU 从内存中读取指令,并解析指令中包含的操作码和操作数等信息。

  2. 执行:根据指令中的操作码和操作数,CPU 进行相应的逻辑或算术运算,并将结果保存到寄存器或内存中。

  3. 写回:如果结果需要保存到内存中,则将结果写入内存;否则,将结果保存到寄存器中供后续指令使用。

  4. 重复:不断重复上述步骤,直到程序执行结束。

    image-20230502142129433

设置PC初始值,操作系统会自动取指执行

image-20230502142344246

有IO指令和没有IO指令执行时间之比:

image-20230502142553500

可以看出IO执行特别慢,CPU利用率非常低

如何解决这个问题?

在等待IO过程中,CPU切出去执行其他程序,让CPU充分忙碌起来,提高了利用率

image-20230502143409536

2.多道程序,交替执行

举例单道程序和多道程序CPU利用率对比:

image-20230502143525988

这种多道程序同时出发,交替执行就是并发

CPU应该工作的样子:

3.如何做到并发?

对于切换程序执行,因为ax,bx改变了,只修改寄存器PC不能找到原来程序执行到哪里。

在切出程序后,原来的程序执行到哪里,执行的样子 需要记录下来,切回时才能继续执行

image-20230502144655677

由此看出 运行的程序和静态程序不一样:运行的程序需要记录运行后的时刻

4.进程

进程:刻画运行中的程序 一个运行中的程序就是一个进程

进程有开始、有结束,程序没有

进程会走走停停,走停对程序无意义

进程需要记录ax,bx,…,程序不用

记录这些信息的数据结构就是:PCB

多个程序同时运行就是多进程,CPU进行管理。

image-20230502145139664

PCB中记录了操作系统所需的,用于描述进程的当前情况以及控制进程运行的全部信息。

操作系统根据PCB来对并发执行的进程进行控制和管理。

二、多进程图像

1.多进程图像是操作系统的核心图像

从上层用户的角度看:共有三个进程PID:1 PID:2 PID:3

操作系统根据PCB合理推进执行多个进程

image-20230502145842480

启动了的程序就是进程,所以是多个进程推进操作系统只需要把这些进程记录好、要按照合理的次序推进(分配资源、进行调度)这就是多进程图像。

我们每要解决一个任务,计算机都会创建一个进程来执行这个任务。 多进程图像是操作系统的核心图像

image-20230502150123795

windows任务管理器中可以查看多个进程同时执行,操作系统通过管理进程实现对计算机的管理

2.多进程如何组织?

通过PCB形成一系列数据结构,操作系统推进进程的执行

image-20230502151012078

3.进程状态图:

多进程的组织:PCB+状态+队列

运行->等待; 运行->就绪; 就绪->运行…

进程状态图能给出进程生存期的清晰描述,是认识操作系统进程管理的一个窗口。

image-20230502151422884

挂起:挂起是指操作系统将某个正在运行的进程暂时停止执行,并将其状态保存到外部存储器或内存中,直到以后再次恢复该进程执行。是一种重要的管理和优化技术,它可以减少系统资源的浪费,提高系统的响应速度和可用性。

在进程挂起期间,进程的状态信息被保存到外部存储器或内存中,当操作系统需要重新启动该进程时,可以从保存的状态信息中还原该进程的上下文,继续执行。

主动挂起:是指进程自己向操作系统申请挂起自己的状态,通常是因为当前执行的任务已经完成,但该进程还需要保留下来,以便稍后根据需要进行继续执行。例如暂停操作、文件下载中暂停/继续操作等

被动挂起:是指操作系统强制挂起某个正在执行的进程,因为系统资源已经不足,或者该进程所请求的资源无法获得,此时操作系统会暂时停止该进程执行,以便其他进程可以更好地利用系统资源。

image-20230502152010758

4.多进程如何交替?

image-20230502152250764

image-20230502152328824

image-20230502153132437

5.多进程如何影响?

多个进程同时在存在于内存会出现下面的问题

进程1中地址100访问到了同时运行的进程2中的地址100:

image-20230502153443915

解决的办法:

限制对地址100的读写

多进程的地址空间分离: 内存管理的主要内容

为什么说进程管理连带内存管理形成多进程图像?

image-20230502155415599

6.多进程如何合作?

队列中的进程放入和取出 多个进程交替执行

image-20230502160047306

生产者—消费者实例

image-20230502160217824

共享缓冲区:

image-20230502160227090

两个合作的进程都要修改counter:

counter语义错误:初始counter=5,进行加一减一应该还是五,但经过执行序列得到的counter为4,进程必须合理推进

image-20230502160634046

核心在于进程同步:

image-20230502160852631

读写PCB,OS中最重要的结构,贯穿始终

三、用户级线程

1.资源切换(引出线程概念)

如何将资源不动而切换指令序列?

线程切换分为指令切换 和 资源切换 分治

进程 = 资源 + 指令执行序列

将资源和指令执行分开一个资源 + 多个指令执行序列

既有多个指令在同时触发交替执行,切换也不用那么复杂:

image-20230502161503545

线程: 保留了并发的优点,避免了进程切换代价

实质就是内存映射表不变而PC指针改变

多个执行序列+一个地址空间是否实用?

一个网页浏览器: 同时触发,交替执行:

一个线程用来从服务器接收数据

一个线程用来显示文本

一个线程用来处理图片(如解压缩)

一个线程用来显示图片

下载一段网页——显示文本——再回来下载图片…

这些线程要共享资源吗?

接收数据放在100处,显示时要读… 写入读出缓冲区

所有的文本、图片都显示在一个屏幕上

多线程表达的切换指令序列对进程切换很有价值。

2.线程切换

启动多个线程,每个线程执行函数

image-20230502162606485

核心是Yield…

能切换了就知道切换时需要是个什么样子

Create就是要制造出第一次切换时应该的样子

image-20230502163116280

如果继续往下执行跳转到另一个线程,因为两个线程共用了一个栈

每个指令序列中,函数调用应该用自己的栈!!!

从一个栈到两个栈

TCB任务控制块,包含了线程的信息,如寄存器状态、堆栈指针、优先级、资源占用等

TCB 在任务/线程切换时用于保存当前任务/线程的状态信息,以便后续再次恢复执行

image-20230502163914093

(jmp 204;应该去掉)

ThreadCreate的核心就是用程序做出三样东西:

image-20230502164005731

多个程序出现在内存中执行,在程序执行的过程中调用Yield(),首先切换栈然后再弹栈,实现切换到另外一个线程执行,在Yield()…

image-20230502164114050

3.用户级线程与核心级线程

如果进程的某个线程进入内核并阻塞

一旦一个线程阻塞,其他线程也将被阻塞,会切换到另一个进程执行

虽然通过用户级线程启动多个序列,但是CPU发生阻塞等待

image-20230502165025062

核心级线程ThreadCreate是系统调用,会进入内核

TCB在内核中,内核中一个线程阻塞,将会切换到另一个线程执行

因此内核级线程的并发性更好

image-20230502165057804

核心级线程完全由操作系统在内核中决定,比用户级线程复杂

四、内核级线程

image-20230502174313995

和用户级相比,核心级线程有什么不同?

ThreadCreate是系统调用,内核管理TCB,内核负责切换线程

如何让切换成型? ——内核栈,TCB

用户栈是否还要用?执行的代码仍然在用户态,还要进行函数调用

一个栈到一套栈:两个栈到两套栈

1.用户栈和内核栈之间的关联

用户栈和内核栈是操作系统中两个重要的栈空间,它们分别用于存储用户态和内核态的执行环境

当一个进程从用户态切换到内核态时,需要使用到内核栈。进程从内核态返回用户态时,需要使用到用户栈

·所有中断(时钟、外设、INT指令)都引起上述切换

·中断(硬件)又一次帮助了操作系统…

image-20230502174609947

用户栈和内核栈是操作系统中两个不同的栈区域,它们各自负责存储不同执行环境的栈帧信息

在处理器发生中断时,或者进程主动发起系统调用时,CPU会切换到内核态,并将当前进程的用户态上下文信息保存到它的用户栈中,然后切换到内核栈中继续执行相应的内核代码;当内核完成相应的处理逻辑后,再将内核栈中保存的内容弹出,恢复用户栈中保存的用户态上下文信息,最后切换回用户态继续执行用户进程。

在这里插入图片描述

2.开始内核中的切换:switch_to

switch to:仍然是通过TCB找到内核栈指针;然后通过ret切到某个内核程序;最后再用CS:PC切到用户程序

switch to也称为上下文切换,当多个任务或线程同时运行时,操作系统需要在它们之间进行快速的切换,实现并发执行

image-20230502175136083

“五段论”保证了线程之间的正确切换和执行:

.

用户级线程、核心级线程的对比:

用户级线程是由应用程序开发者创建和管理的线程,运行在用户空间,并通过用户程序调用系统调度库来实现线程的调度和同步

每个用户级线程都对应着一个内核级线程,内核级线程以操作系统内核的身份运行并提供线程与系统资源之间的映射

用户级线程实现简单,调度和同步开销小,缺点是不能利用多处理器环境提高性能

核心级线程是由操作系统内核创建和管理的线程,直接由内核调度器进行调度

与用户级线程相比,内核级线程有更好的并发性和CPU利用率,但比较复杂。

image-20230502175445288

五、内核级线程实现

内核级线程需要采用复杂的数据结构来维护线程上下文切换和状态信息,并且需要在内核态进行线程切换

核心是让操作系统内核直接管理线程调度,对于上层应用程序来说,无需关心线程的创建、调度和同步等

先从用户栈到内核栈,再从内核栈到用户栈;核心级线程的两套栈,核心是内核栈。

image-20230502181132793

1.int 0x80 fork( )

fork() 系统调用可以让程序生成一个新的独立进程,并在原进程和新进程中进行不同的操作

image-20230502181334942

2.切换五段论中的中断入口和出口

中断入口: _system_call将用户态信息压栈

任务的运行状态如果不在就绪状态就执行调度,如果在就绪状态但counter等于0,也执行调度程序

image-20230502182606646

中断出口:

sys_fork 函数调用了 fork() 系统调用,它会通过 eax 寄存器返回新创建进程的进程 ID,在此之前会先将该寄存器的值入栈保存

接着通过 cmp 判断是否需要进行进程调度,并将返回地址入栈后通过 jmp 指令跳转到 schedule 函数执行进程切换操作

在进程切换结束后,通过 pop 指令将原 eax 寄存器的值恢复回来fork() 调用的返回值

image-20230502191217631

3.switch to

任务状态段Tss(Task State Segment)表示任务状态段的表项,用于获取相应进程的任务结构体的起始地址

跳转到所切换到的进程的任务结构体中保存的代码起始地址,从而实现进程上下文切换的操作:

image-20230502191516243

Linux 0.11用tss切换,但也可以用栈切换,因为tss中的信息可以写到内核栈中

4.ThreadCreate

fork()使用 push 指令将寄存器 %gs 和 %eax 的值分别压入栈中

然后并调用_copy_process 函数创建新进程

·在 _copy_process函数中,使用给定的参数构造一个新进程的状态

image-20230502192008442

这些参数全部传入 _copy_process函数设置上下文信息

然后函数返回到 sys_fork 函数并使用 add 指令来从栈中删除参数,最终 ret 返回

image-20230502192040042

copy_process的细节:创建栈

调用 get_free_page 函数来动态申请一页大小的内存空间,并转换为一个指向PCB的指针 p

创建TCB——创建内核栈和用户栈——关联栈和TCB 子进程和父进程共享用户栈

image-20230502192152064

image-20230502192251001

copy_process的细节:执行前准备

image-20230502192428070

5.如何执行我们想要的代码?

fork() 调用成功时,返回值为子进程的 PID 在父进程中。在子进程中,fork() 返回 0。

exec() 是一个系统调用,会执行 system_call

image-20230502192822690

ex.a_entry是可执行程序入口地址,产生可执行文件时写入

image-20230502193129842

内核级线程总结

image-20230502193145610

六、操作系统的“树”(知识串讲总结)

前面知识的串联

image-20230502193508323

image-20230502193553081

image-20230502193601564

image-20230502193610436

image-20230502193634256

image-20230502193646787

image-20230502193655477

image-20230502193709439

image-20230502193723501

image-20230502193739971

image-20230502193755327

image-20230502193812104

image-20230502193819029

image-20230502193826812

image-20230502193834332


更多操作系统笔记:【哈工大李治军老师】操作系统笔记专栏汇总

大家的点赞、收藏、关注将是我更新的最大动力!欢迎留言或私信建议或问题。 大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!

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

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

相关文章

58.网页设计规则#5_阴影

一些概念 ● 在一个100%平面设计的时代之后&#xff0c;我们现在又回到了在UI设计中使用阴影(“平面设计2.0”) ● 阴影箱深度(3D):阴影越多&#xff0c;离元素界面越远 利用好阴影 你不必使用阴影!只在对网站个性有意义的情况下使用它们 使用少量的阴影:不要给每个元素…

Jmeter接口自动化测试系列之Http接口自动化实战

以下主要介绍Jmeter接口自动化需要哪些控件、接口自动化实战及总结。 前面的系列文章&#xff0c;介绍了常用组件、参数化、接口依赖、断言等知识点&#xff0c;今天我们要将这些结合起来&#xff0c;进行综合实战。 2023年B站最新Jmeter接口测试实战教程&#xff0c;精通接口…

从一到无穷大 #5 公有云时序数据库定价

文章目录 引言serverless实例售卖结论 Azure CosmosDB预配吞吐量自动缩放吞吐量Serverless预留容量存储量 Amazon Timestream写入计费查询计费存储 阿里云TSDB阿里云Lindom时序引擎实例固定费用存储费用节点费用 华为云GaussDB(for Influx)腾讯云CTSDBTDengineInfluxDB CloudAW…

c++11下篇 + 智能指针

c11下篇 智能指针 1 可变参数模板1.1 递归函数方式展开参数包1.2 逗号表达式展开参数包1.3 STL容器中的empalce相关接口函数&#xff1a; 2 lambda达式2.1 c的痛2.2 lambda表达式语法2.3 函数对象与lambda表达式 3 包装器3.1 bind 4 线程库4.1 thread类的简单介绍4.2 面试题&a…

MySQL示例数据库(MySQL Sample Databases) 之 world_x数据库

文章目录 MySQL示例数据库(MySQL Sample Databases) 之 world_x数据库官方示例数据介绍world_x数据库world_x数据库安装world-db/world.sql的脚本内容参考 MySQL示例数据库(MySQL Sample Databases) 之 world_x数据库 官方示例数据介绍 MySQL 官方提供了多个示例数据库&#…

差分数组 技巧小记

差分数组 差分数组二维差分 差分数组 如果两个信息“长得很像”&#xff0c;只要保留一个&#xff0c;对另一个&#xff0c;只要保留它们的差异&#xff0c;然后进行微调就行了。 差分数组&#xff1a; 3210&#xff0c;3208&#xff0c;3206&#xff0c;3211&#xff0c;32…

Three.js--》Gui.js库的使用讲解

目录 Gui.js库基本使用 使用three自带gui库实现基本操作 gui库实现下拉菜单和单选框 gui库分组方法实现 使用dat.gui第三方库 Gui.js库基本使用 gui.js说白了就是一个前端js库&#xff0c;对HTML、CSS和JavaScript进行了封装&#xff0c;学习开发3d技术时借助该库可以快速…

230502-LLM-Vicuna介绍、安装与注意事项整理

最终效果 在对话过程中&#xff0c;GPU与CPU均会有波动&#xff0c;但是主要还是CPU波动为主 相关资料 序号链接说明001本地CPU6G内存部署类ChatGPT模型&#xff08;Vicuna 小羊驼&#xff09; - 知乎极简安装版本&#xff0c;只支持CPU与命令行002最新开源语言模型 Vicuna 媲…

【Linux进阶之路】初始Linux

文章目录 一.时代背景二.硅谷发展模式三.操作系统基本定义常见的操作系统Linux系统的常见安装方式 四.基本指令的使用登录指令与用户相关的指令ls 指令——信息查看pwd指令——打印当前所处的文件位置cd指令——访问文件rm——删除指令touch——创建文件与修改文件信息tree ——…

Rust - 变量与数据的交互方式(clone)

在上一篇文章中我们介绍了变量与数据的交互方式-move&#xff0c;通过底层原理我们知道Rust 永远也不会自动创建数据的 “深拷贝”。因此&#xff0c;任何 自动的复制可以被认为对运行时性能影响较小。 但是如果我们 确实需要深度复制 String中堆上的数据&#xff0c;而不仅仅…

RT1010 PWM 组成配置和 PWMX 的使用

1. 前言 本篇博文将着眼于 i.MX RT1010 内部的 eFlexPWM&#xff0c;介绍其各个功能模块&#xff0c;以及 PWM 产生的原理。 2. 功能模块组成 以下是 RT1010 内部 PWM 的一个 Submoudle 的组成框图&#xff0c;从框图中我们可以看到&#xff1a; 自左向右依次有 Prescaler 对…

【C++入门】C++为什么要有缺省参数

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

后端程序员的前端必备【Vue】- 01 Vue入门

Vue概述与基础入门 1 Vue简介1.1 简介1.2 MVVM 模式的实现者——双向数据绑定模式1.3 其它 MVVM 实现者1.4 为什么要使用 Vue.js1.5 Vue.js 的两大核心要素1.5.1 数据驱动![请添加图片描述](https://img-blog.csdnimg.cn/963aca7d7a4447009a23f6900fdd7ee1.png)1.5.2 组件化 2 …

IDEA2022版教程上(下载、卸载、安装、新建工程、jdk设置、详细设置、新建/导入/删除 普通java模块、修改普通java模块名、同时打开多个工程、常用代码模板:非空判断,遍历,输出语句快捷键)

0、前景摘要 0.1 概览 0.2 套课程适用人群 初学Java语言&#xff0c;熟悉了记事本、EditPlus、NotePad或Sublime Text3等简易开发工具的Java初学者熟练使用其他Java集成开发环境&#xff08;IDE&#xff09;&#xff0c;需要转向IDEA工具的Java工程师们关注IDEA各方面特性的J…

BPMN2.0 任务-脚本任务

描述 脚本任务(script task)是自动执行的活动。当流程执行到达脚本任务时,会执行相应的脚本。 脚本任务用左上角有一个小“脚本”图标的标准BPMN 2.0任务(圆角矩形)表示。 脚本任务使用script与scriptFormat元素定义。 <scriptTask id="theScriptTask" nam…

Qt中的绘图事件

文章目录 QPainter 绘图绘图设备QPixmap QPainter 绘图 绘图事件 void paintEvent()声明一个画家对象 QPainter painter(this) this指定绘图设备画线、画圆、画矩形、画文字设置画笔 QPen 设置画笔宽度 、风格设置画刷 QBrush 设置画刷 风格 测试 #include "widget.h&quo…

科学计算库Numpy快速入门

目录 Numpy概述array数组数组结构数组类型数值运算排序操作数组形状操作数组生成函数四则运算随机模块文件读写 Numpy概述 NumPy 是 Python 中的一个开源数学库&#xff0c;提供了快速且便捷的数组处理功能&#xff0c;可以用来进行科学计算、数据分析、算法开发等多种任务。N…

InnoDB 磁盘结构及表空间 ( Tablespaces )

InnoDB磁盘主要包含Tablespaces&#xff0c;InnoDB Data Dictionary、Doublewrite Buffer、redo log和Undo Logs Tablespaces: 表空间分为系统表空间&#xff08;ibdata1文件&#xff09;、临时表空间、常规表空间、Undo表空间以及file-per-table表空间。系统表空间又包括双写…

CDH6.3.2-组件安装安全认证

HDFS 1.选择自定义。 2.选择HDFS ZK YARN然后点继续。 3.选择安装的主机。 4.审核更改默认就行&#xff0c;点继续。 5.配置HDFS的HA。 安装好以后点击hdfs进入实例就能够看到启动了高可用。 6.启动YARN的高可用。 KAFKA 更具需求修改资源 一直点继续就行了 FlUME HI…

CTF权威指南 笔记 -第二章二进制文件- 2.3 -静态链接

目录 地址空间分配 两个链接的方式 按序叠加 相似节合并 静态链接的详细过程 虚拟内存 重定位文件 静态链接库 地址空间分配 我们把之前的两函数分为两个文件 main.c extern int shared extern vooid fun(int *a,int *b); int main(){int a100;func(&a,&share…