操作系统笔记三
进程
把一个静态程序通过OS在内存中让cpu执行起来的动态执行过程叫进程
写代码都是用户态,而进程在执行过程中需要完成特定的功能,这些功能呢只有操作系统能提供,比如说读写文件,读写文件的过程是与硬盘打交道,这个过程需要操作系统来完成,所以说进程只需要给操作系统发出请求,操作系统代表进程在内核中执行,那么这个时候进程处于核心态
特点
动态性:动态创建,结束进程
并发性:可以被独立调度并占用cpu运行。可能一段时间有多个进程在执行,给人一种并行的感觉(一个时刻多个进程,只有多核cpu能实现),实际为并发
独立性:不同进程的工作不相互影响。通过页表使不同程序访问不同地址空间,越过地址空间会缺页,产生异常。OS给不同进行分配不同的页表,让其各自在独立的空间中运行
制约性:不同进程间可能有交互,或者一个进程需等待另一进程执行到一定阶段才能继续执行。因访问共享数据/资源或进程间同步而产生制约
程序 = 算法 + 数据结构
描述进程的数据结构:进程控制块PCB
OS为每个进程维护一个PCB,保存与进程有关的各种状态信息
PCB
OS管理进程运行所用的信息集合。OS用PCB描述进程基本情况及运行变化过程。PCB是进程存在的唯一标志
进程创建:生成一个PCB
进程终止:回收它的PCB
根据进程的个数是否固定会否频繁插入删除选择不同类型
进程状态
生命周期管理 :
创建:3种事件:1.系统初始化时。2.用户请求创建一个新进程。3.正在运行的进程执行了创建进程的系统调用
运行:内核选择一个就绪进程,占用cpu并执行
等待/阻塞:3种情况:1.请求并等待系统服务,无法马上完成。2.启动某种操作,无法马上完成。3.需要的数据没有到达。
进程只能阻塞自己,因为只有进程自身知道何时需要等待某种事件发生
唤醒:原因:1.被阻塞进程所需的资源可被满足。2.等待的事件到达。3.将该进程的PCB插入就绪队列。
进程只能被别的进程或OS唤醒
结束:1.正常退出,自愿。2.错误退出,自愿。3.致命错误,强制。4.被其他进程所杀,强制
三种基本状态:
运行状态:正在cpu上运行
就绪状态:获得除cpu外的一切所需资源,一旦得到cpu即可运行
等待状态:等待某一事件而暂停运行。如等待资源,等待输入/输出完成
Null -->New:产生新进程来执行一个程序
New -->Ready:进程创建完成并初始化后,一切准备就绪。不会很久
Ready -->Running:进程被OS调度,分配到cpu上运行
Running -->Exit:进程完成或因出错,由OS作结束处理
Running -->Ready:由于分配它的cpu时间片用完而让出cpu。由OS来完成
Running -->Blocked: 请求某样东西且必须等待
Blocked -->Ready:进程等待的事件到达
进程挂起
挂起:意味着进程没有占有内存空间,处在挂起状态的进程映像在磁盘上
OS看到的是一系列进程,需要选择哪个进程去执行,以及哪个进程要切换状态
线程
读硬盘的速度远低于cpu运行速度,可能要等半天才能解压
因此需要一种新的实体,实体间可以并发执行,共享相同的地址空间(与进程不同,进程间地址空间是独立的)。这就是线程
线程分为两部分:一部分是资源管理,包含地址空间,打开的文件、访问的网络等等。一部分是执行功能,现在这个执行状态交由线程管理
代码在进程这个资源管理平台上的一条执行的流程,认为是线程
线程控制块TCB:只负责管理跟执行流程相关的一系例信息。包含程序计数器PC,堆栈SP,寄存器信息(有不同的执行流,控制流,需要通过一系列的寄存器表示控制流的执行状态)。它的内存空间(堆空间),数据空间,代码段是所有线程所共享的
在高频计算里面很强调性能,而且它所执行的代码相对统一,不会出现一个代码出现不同的控制流程,强调性能的需要使用线程来完成。
另外一方面,比如浏览器,打开一个网页就可以用线程的方式来实现,打开不同的网页都很快,如果用线程的机制,可能有的网页有恶意代码或者有bug导致这个线程崩溃了,就有可能引起整个进程的崩溃,你可能打开很多网页,这些网页都崩溃。这也是早期浏览器很多采用线程实现,现在的浏览器都采用进程来实现。这个适合进程
线程是具有同一个地址空间的,属于同一个进程的线程拥有同一个页表,切换的时候不要切换页表。
而对于进程而言,我们要切换进程的话,需要把页表也切换掉,而这个切换页表的开销是比较大的,因为这里面涉及到它们访问的地址空间不一样,它里面的很多cache信息,很多TLB信息,硬件的信息,都会失效,需要重新加载。那么这个开销比较大。
线程切换的时候,由于共享页表,重用,不用做失效处理,效率会很高
线程的实现
3种实现方式:
用户线程:在用户空间实现。OS看不到的线程,由专门的用户线程库来进行管理
内核线程:在内核中实现。由OS管理起来的线程
轻量级进程:在内核中实现,支持用户线程
用户线程与内核线程的对应关系
多对一:多个用户线程对应一个内核线程
一对一:一个用户线程对应到一个内核线程
多对多:n个用户线程对应到m个内核线程
线程控制块TCB在库里面实现,OS看不到TCB,只能看到整个进程的信息。进程里的线程信息是由管理库来实现
在用户空间实现线程机制,不依赖于OS的内核,由一组用户级的线程库函数来完成线程的管理。包括线程的创建、终止、同步和调度等
用户线程的维护由相应进程完成(通过线程库函数),不需要OS内核了解用户线程存在,可用于不支持线程技术的多进程操作系统
每个进程都需要自己私有的TCB列表,用来跟踪记录各个线程的状态信息(PC,栈指针,寄存器)。
用户线程切换也由线程库函数完成,无须用户态/核心态切换,所以速度很快
运行每个进程有自定义的线程调度算法
缺点:
如果一个线程发起系统调用而阻塞,整个进程将等待。其他线程也会被等待
当一个线程开始运行后,除非主动交出cpu使用权,否则其进程里的其他线程将无法运行。用户态线程库没法主动打断当前用户线程的执行。OS可以,OS会管理中断,一旦产生中断,整个cpu控制权会回到OS手里,OS对中断可以进行进一步处理。特别是时钟中断。
时间片是分配给进程,因此与其他进程相比,多线程执行时,每个线程得到的时间片会更少一些,执行会较慢
所有属于一个进程的线程都被对应PCB统一管理,具体调度时由TCB完成。
只要完成一次切换,就会有一次用户态/内核态的变换。开销更大
上下文切换
各个进程共享cpu资源,不同时候需要切换不同进程占用cpu执行。切换过程称为上下文切换。
进程上下文切换,切换的是进程所用到的寄存器,寄存器是和CPU紧密相连的,意味着在操作系统里面实现进程切换的话,要关注操作系统所载的CPU,它到底具有哪些寄存器,以及这些寄存器哪些是被进程所使用的
进程运行时需要的寄存器:
程序寄存器,它指出了进程执行到什么地方
栈指针也是寄存器,可以知道调用关系以及相应的变量位于什么位置。
等等
这些信息在做进程切换的时候,需要把这些信息保存到进程控制块中的某个位置,保存之后呢,当运行另外一个进程的时候,需要把这个寄存器从那个进程控制块中取出来,甚至context这么上下文取出来,然后恢复到CPU里面去,相当于把寄存器的资源重新赋好,这使得我们接下来这个进程可以继续在CPU上执行
进程必须在切换之前存储许多部分的进程上下文,并且能够在之后恢复他们,同时速度要快
OS将PCB放在不同的队列里:就绪队列,等待I/O队列(每个设备的队列),僵尸队列
进程创建
unix是用fork/exec 这两个系统调用来完成新进程的创建
所执行的程序是一样的,但是变量有一个地方不一样就是id
父进程是原来执行的id,子进程是新分配的id
完成复制之后,由exec加载一个新的程序加载到内存当中
fork完之后,当前系统就有两个进程,并且这两个进程的当前指令都指向fork完之后的那一行,父进程和子进程执行fork的返回值不一样,子进程返回0,父进程中返回值是子进程pid则跳过括号中的代码
除了返回pid不一样,其他完全一样,根据返回值不同执行不同进程
进程加载/执行
printf(“Why would I execute?”),放在这是做一个提醒作用, 如果执行了exec这个系统调用之后,当前这个子进程的地址空间里面代码段已经被覆盖了,也意味接下来这条语句(printf(“Why would I execute?”))代码的内容已经被新的程序程序覆盖了,这句话根本执行不到如果执行到,肯定是出了什么问题,比如exec失败了
最后有一个wait,后面会讲到,等待子进程结束,因为这个pid,大于0,其实就是代表子进程的pid号,假设wait返回了,也就意味着子进程结束了
执行fork之后,代码和数据都复制了一份
ork是要把父进程的地址空间完全复制一份到子进程中来,这里有一个内存的大量拷贝,需要把代码段数据段全都拷贝到另一进程地址空间中去,但是接下来执行exec的时候,刚才所做的拷贝全都没有用,因为要去还在新的程序,要把代码段,数据段给重新覆盖掉,所以前面做的fork的拷贝是多余的
优化:
1.vfork,早期unix系统提供的一种手段,做fork的时候只是复制y一小部分,j绝大部分都没有复制,因为它知道调完vfork之后,我们的程序会紧接着调用exec,使得效率高。但是这个增加了编程人员的开销,增加了一个fork和vfork
2.编程人员还是只有fork一个系统调用就行了,而不需要考虑什么时候后面程序是执行exec还是不执行exec的系统调用好。操作系统里面,各个子系统之间是相互支持相互帮助的,我们通过虚存管理,就可以实现一个高效的fork实现机制,这里面有个技术叫copy on write (COW). 就是写的时候再进行复制。当父进程创建子进程的时候,如果是采用COW技术,我们在做实际的子进程地址空间复制的时候,并没有像之前一样把整个地址空间真实的复制,而只是复制,父进程地址空间所需要的元数据,这些元数据其实就是页表,他们指向同一块内存空间,当父进程或者子进程对某一个地址单元进行写操作的时候,会触发一个异常,使得无论是父进程还是子进程,要完成一个操作,就是把触发异常的这个页给他复制成两份,使得我们父进程和子进程分别有不同的地址。通过这种方式,可以实现按需的一种情况。按需写的一种情况复制,如果你全部做只读,我确实没必要复制。只有当写的时候,这个父进程和子进程有不同的页表
进程等等/终止
父进程就可以帮助子进程完成最后一步,把它在内存中的资源释放掉,最主要的就是PCB.
调度
在某个时刻决定选择那个就绪进程去占用CPU执行。
目标:使得系统效率更高
什么时候调度:从一个状态到另一个状态变化的时候触发一次调度。因为这个都是否考虑让新的进程执行,或者让当前进程从CPU上撤下来,换一个进程去执行,这实际上就是调度时机,或者称为调度点
用户态抢占和非抢占
非抢占式:进程启动后,别的进程不能打断,导致别的进程必须等待这个进程执行完毕才去执行。效率不高
抢占式:用户进程在它的执行过程中,它感知不到,操作系统会决定,在某个时刻打断当前用户进程的执行,让操作系统去选择另外一个进程执行(操作系统认为更值得去执行的进程)称之为抢占式调用。现在操作系统常用调度策略
内核里面也存在是否可以抢占,
内核态非抢占:当一个用户进程执行系统调用,如果这个系统调用在内核中不会导致这个进程处于等待状态,它还是执行状态,这个时候,当这个系统调用返回的时候,一定会返回到发起这个系统调用的进程中去继续执行,意味着内核中不会出现抢占现象,不会在内核中切换,切换到另一个线程去执行,只要你这个进程在内核中执行,这个流程中它自身不会出现从运行态到阻塞态的变化,就确保回去的时候一定是,发起请求的进程继续执行。
内核态抢占:如果内核中也允许去做抢占,就是说有可能正在执行的系统调用,在内核里面执行的系统调用,某一个进程发起的,结果由于特殊事件产生,需要把当前内核完成一次切换,切到另一个优先级更高的进程去执行,一旦之前那个系统调用返回的时候,在内核那一点,是从内核态返回用户态的时候,可能变成另一个进程去,这种情况称之为抢占式的内核
调度原则
调度算法
来了新的执行时间更短的进程
1 新进程继续放到就绪队列里面去,排在就绪队列最前面,但是它不会打断当前正在运行的进程Pw,这种非抢占方式。
2 抢占式的,就是说,当Pw在执行的时候,比如执行完一个时间片,还剩余执行事件8(之前是9),这是来了一个新进程,执行时间是5,比较下正在执行的剩余时间和这个新的进程执行时间,新进程执行时间更小,它剩余的时间只有5,虽然它没有被执行,这个时候就要完成一次抢占,当前正在运行的进程从运行态-》就绪态,重新放回就绪队列里面去,让新进程占用CPU继续执行
p4p5各少了一个p3的执行时间,但是p3多了p4和p5的执行时间
根据过去执行时间预估未来执行时间
轮循调度算法
设置时间片20,轮流分享时间片,每20的时候让出cpu
q是时间片
多级反馈队列
公平共享调度
实时调度
实时调度首先面向的系统不一样。就是 real time system 实时系统
实时系统更多的是用在工业控制,如火车或者一些机床,或者一些嵌入式工厂里面,控制环境里面需要确保某一些任务需要能够在规定时间之内必须完成,这个规定时间就是real time一个体现,要在将来某段时间内必须完成某件事情,这个时间是确定的
静态:在任务执行前确定优先级
动态:任务随着执行过程中优先级会有变化
多处理器调度
1 放到哪个CPU执行,2确保系统是一个负载平衡的状态
相关文章:

操作系统笔记三
进程 把一个静态程序通过OS在内存中让cpu执行起来的动态执行过程叫进程 写代码都是用户态,而进程在执行过程中需要完成特定的功能,这些功能呢只有操作系统能提供,比如说读写文件,读写文件的过程是与硬盘打交道,这个过程…...

uniapp快速入门教程,内容来源于官方文档,仅仅记录快速入门需要了解到的知识点
uniapp快速入门教程,内容来源于官方文档,仅仅记录快速入门需要了解到的知识点 目录 介绍uniapp 介绍uniapp x 介绍功能框架图创建项目&发布组件/标签的变化js的变化css的变化工程结构和页面管理 pages.jsonmanifest.json 应用配置组件easycom组件规…...

基于微信小程序的商品展示+ssm(lw+演示+源码+运行)
商品展示系统 摘 要 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,微信小程序被用户普遍使用,为方…...

【Linux】常用指令(下)(内含more、less、 head、tail、date、find、grep、zip、tar以及学习笔记)
文章目录 前言1. more指令2. less指令(重要)3. head指令4. tail指令5. 管道(做到学会使用即可)6. date指令6.1 时间戳 7. cal指令8. find指令9. grep指令10. zip/unzip指令11. tar指令 前言 Linux下的常用指令终于要在本文落下帷…...

DesignMode__unity__抽象工厂模式在unity中的应用、用单例模式进行资源加载
目录 抽象工厂模式 思维导图 接口(抽象类) 工厂接口 抽象产品类 抽象武器接口 抽象人物接口 具体工厂和具体产品 具体工厂 (1)产品接口,生成具体人物 (2)武器接口,生成具体…...

Leetcode3289. 数字小镇中的捣蛋鬼
Every day a Leetcode 题目来源:3289. 数字小镇中的捣蛋鬼 解法1:哈希 代码: /** lc appleetcode.cn id3289 langcpp** [3289] 数字小镇中的捣蛋鬼*/// lc codestart class Solution { public:vector<int> getSneakyNumbers(vector…...

13_Python的高阶函数
高阶函数 高阶函数是Python编程中一个非常强大和有用的特性,它们允许程序员编写更简洁、更抽象的代码。 Python中的高阶函数是那些至少满足以下一个条件的函数: 接受一个或多个函数作为输入(也就是说,它的参数之一是函数&#…...
清空当前机器所有Docker容器和镜像
sudo docker stop $(sudo docker ps -aq) sudo docker rm $(sudo docker ps -aq) sudo docker rmi $(sudo docker images -q)删除当前机器上的所有Docker镜像是一个高风险操作,因为它会删除所有镜像,包括那些可能正在被容器使用的镜像。在执行此操作之前…...
FreeRTOS学习——Systick中断、SVC中断、PendSV中断
FreeRTOS学习——接口宏portmacro.h,仅用于记录自己阅读与学习源码 FreeRTOS Kernel V10.5.1 port :GCC/ARM_CM7 文章目录 Systick源码触发方式 SVC源码触发方式 PendSV源码触发方式 相关汇编指令 Systick 源码 在Systick中断xPortSysTickHandler中&am…...
汇量科技大数据面试题及参考答案
如何在 SQL 中处理三个字段完全一样的去重?在 Scala 中又该如何实现? 在 SQL 中,可以使用多种方法来处理三个字段完全一样的去重。一种常见的方法是使用 DISTINCT 关键字结合多个字段来实现。例如,假设有表 table_name,包含字段 field1、field2 和 field3,可以使用以下 S…...

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.AVL树
1.AVL 树 1.1AVL 树的概念 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查 找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii 和E.M.Landis在1962…...
Python 的数据类型与操作
一、常用内置类型(Built - in Types) Python 拥有多种内置数据类型,这些类型满足了各种编程需求,从简单的数据存储到复杂的数据结构表示。 1. 数值类型(Numeric Types) 整数(int)&a…...

Python燃烧废气排放推断算法模型
🎯要点 宏观能耗场景模型参数化输入数据,分析可视化输出结果,使用场景时间序列数据模型及定量和定性指标使用线图和箱线图、饼图、散点图、堆积条形图、桑基图等可视化模型输出结果根据气体排放过程得出其时间序列关系,使用推断模…...

Qt中多语言的操作(以QtCreator为例)
1、首先,我们在代码中与文本相关的且需要支持多语言的地方,用tr来包含多语言key(多语言key是我们自己定义的),如下 //举例 QPushButton* btnnew QPushButton(this); btn->move(20,20); btn->resize(100,50); //…...

计算机毕业设计 社区医疗服务系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...

html+css学习
html 元素 html元素是HTML的根元素,一个文档只能有一个,其他所有元素都是其后代元素 html有一个属性为lang,其作用是: 帮助语言合成工具确定要使用的发音帮助翻译工具确定要使用的翻译规则 当属性lang“en”则表示告诉其浏览器…...
2.gitlab ce 细粒度的权限控制
需求: 在提交merge reqeust时,必须指定审核人,并且要选审核人清单里的 有个code owners应该可以做到(gitlab ce应该也可以用) 下面是参考的文档 细粒度的代码权限怎么做?极狐GitLab 代码所有者来帮忙 -…...
G - Merchant Takahashi / F - Useless for LIS
G - Merchant Takahashi 首先考虑暴力 DP。 设最后一步走到编号 ii 的城镇的方案的最大收益为 fifi,则每次集市相当于是 fTi←fj−C∣Ti−j∣Pi(1≤j≤n)。 这样每次可以通过枚举 j 来转移,这样总时间复杂度是 O(nm) 的&…...
自然语言处理实例
引子:基于聊天机器人项目的自然语言处理(NLP)学习路线 自然语言处理(Natural Language Processing,简称 NLP)是人工智能的重要分支,旨在帮助计算机理解、生成和处理人类语言。NLP 技术广泛应用于搜索引擎、机器翻译、语音识别、文本摘要、情感分析、对话系统等领域。为…...

『功能项目』主角属性值显示【75】
本章项目成果展示 我们打开上一篇74穿戴装备的项目, 本章要做的事情是制作主角属性界面,实现在面板上显示主角的攻击力等数值 制作一个简易的主角界面(创建Image与Text显示即可) 创建一个空物体 重命名为PlayerInfo 在其子级下创…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...

MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...