🍉作者@ Autumn60
🏄欢迎关注:👍点赞🙌收藏✍️留言
👲微语:此去前程远大,你一人,便是千军万马,少年,愿你先折桂花,再筑梦天涯
目录
前言:
定义:操作系统是控制管理计算机系统的硬软件,分配调度资源的系统软件。
目标:方便性,有效性(提高系统资源的利用率、提高系统的吞吐量),可扩充性,开放性。
在操作系统内部,进程又是操作系统进行资源分配的基本单位,这意味着各个进程互相之间是无法感受到存在的,这就是操作系统抽象出进程这一概念的初衷,这样便带来了进程之间互相具备“隔离性”。
进程的特性:隔离性
一、什么是进程 / 任务?
可以理解为:一个运行起来的程序就是进程/任务,一个.exe(可执行文件) 文件,当双击这个程序跑起来之后,就会在系统中形成一个进程;
.exe文件
进程可以通过打开任务管理器(Ctrl + ALT + . 选择任务管理器)来看到进程
上图中的一个个文件就是进程;
上图中有这么多的进程,内存该如何去管理这些进程呢?
(进程多了,则就需要管理)
1.1进程管理:
所谓的管理就是两大步:
1.描述这个进程
2.组织这些进程
例:
比如说一个学校,学校要管理学生(学生很多),这个时候就需要一个学生管理系统来管理
学生管理系统:
1.明确每个学生的各种信息
2.通过数据结构把这些学生的信息存放起来(比如说表格....)
当管理起来之后,对学生进行管理就会很方便,比如说某学生成绩的录入,发奖学金,处分等
1.描述这个进程:
使用结构体 / 类,把一个进程有哪些信息表示出来
1.1进程结构体 :
我们简称PCB(progress control block),这就是一个结构体,里面包含了进程的核心信息;
1.pid: (进程的ID);
每一个进程都需要有一个唯一的标识符简称pid,也就是进程的ID;
2.内存指针 : (进程占用的哪一部分内存);
当前这个进程使用的内存是哪一部分
进程要跑起来就要消耗一定的硬件资源(内存),进程就必须管理这么一块内存空间,以方便使用这就需要通过内存指针来描述当前进程用的是那一部分内存;
3.文件描述符表: (也就是进程运行时,使用了那些硬盘上的资源)
文件:比如硬盘上 存储的数据, 往往都是以文件为单位进行整理的;
进程每一次打开一个文件,就会产生一个 " 文件描述符 "(标识这个被打开的文件),一个进程可能会打开很多文件,就对应了一组文件描述符.把这些文件描述符放到一个顺序表这样的结构里,就会构成 文件描述符表;
4.进程调度
进程调度的基本过程是怎样的?
上面的属性是一些基础的属性,下面的一组属性,主要是为了能够实现进程的调度~
完成进程调度,需要pcb里面提供相关的属性:接下来这一组属性,都是描述和CPU资源相关的属性,而这些属性,都是辅助进程调度的,而程序能运行,全依仗CPU,每个程序,相当于一组"二进制指令"的集合;
CPU有一个概念是核心数:如果说8核16线程(相当于8个人,每个人一个顶两,相当于8个人干16个人的活,8个物理核心,16个逻辑核心);
a.进程状态 :
这个状态就描述了当前这个进程接下来应该怎么调度,简单认为进程状态主要有两个:
1.就绪态:该进程已经准备好了,随时可以上CPU执行;
2.阻塞态:该进程暂时无法上CPU执行;
b.进程的优先级:
进程之间的调度不一定是公平的,有的会优先调度,先给谁分配时间,后给谁分配时间,以及谁分的多,给谁分的少。(这里的优先级只是建议,系统不一定采取)
c.进程的上下文: 也就是记录上次没做完的事,进展到哪里的一个中间状态
上下文,就是描述了当前进程执行到哪里这样的一个“存档记录"
进程在离开 CPU 的时候就要把当前运行的中间结果,给它进行“存档”
相当于玩单机游戏的时候的存档~~
等到下次进程回来 CPU 上再恢复之前的“存档”,从上次的结果继续往后执行~~
把上下文具体到进程的话,具体指就是进程在CPU运行过程中,CPU内部的一系列寄存器的值;
相当于读档继续玩游戏~
存档+读档~存档存储的游戏信息,就称为“上下文”
寄存器:
寄存器有很多种,不展开讲解,其中最典型的作用,就是保存当前进程执行的中间结果,包括进程执行运行到哪一条指令~~
相当于玩单机游戏的时候的存档~~
相当于读档继续玩游戏~
存档+读档~存档存储的游戏信息,就称为“上下文”
d.进程的记账信息:
统计每个进程在CPU上执行的多久!,执行了多少条指令了等等...
有了这个统计,就可以作为进程调度的一个指导依据
5.并发与并行:
1.并行:
并发编程是要同一时刻运行多个任务,做多件事!(同时看qq,听网易云)
同一时刻,两个核心,同时执行两个进程,此刻这两进程就是并行执行的;
2.并发:
一个核心,先执行进程1,执行一会之后,再去执行进程2,再执行一会后,再去执行进程3......此时只要这里的切换速度足够快,看起来,进程1,2,3就是"同时"执行;
如果有200多个任务只有16个核心,也可以同时执行这些任务,通过并发 + 并行 的方式来完成;
而并行 + 并发 完成 ,完全是操作系统自身控制的,程序员也感知不到,所以很多时候把并行 + 并发 统称为 并发;
2.组织这些进程:
使用一定的数据结构,把这些结构体 / 对象放到一起;
操作系统往往是使用 双向链表 这样的结构来组织 pcb ~~;
1.创建一个进程,就是创建一个 链表的节点
2.销毁了一个进程,就是把链表的节点给删除了
3.遍历进程列表,就是在遍历链表;
二、虚拟内存地址:
野指针: 你也不知道它指向哪里,没意义;
比如说你在用浏览器在上图0xa中运行,不小心修改了qq (在0xb中运行) 的数据,此时如果浏览器崩溃掉,qq也会随着崩溃掉,这就会对系统的稳定性产生巨大的挑战,此时就引入了一个概念虚拟内存地址来解决这个问题;
站在这俩进程的角度看,它们的代码中操作的内存地址,就是0x00-0xff这一段;
这里访问的内存就会被操作系统自动映射到真实的物理内存上,但是进程自身感知不到实际的物理地址是啥;
此时如果进程1,bug了( 出现比如野指针,下标越界等异常 ): 此时就没事了
拿着这个野指针的地址,发现页表上就没有这个地址!!也就无法翻译,也就无法真正修改物理内存,也就不会对别的进程内存数据进行干扰
一个进程无法直接干预另外一个进程的内存内容
也就是进程的独立性 , 每个进程都有自己独立的地址空间, 大大提升了操作系统的稳定性;
三、进程间通信
有的时候,需要进程之间相互交互,相互配合,如果每个进程可以直接访问物理内存,其实是没有隔离性,也就不需要进程间通信,进程1直接把算好的结果,写到进程2的内存里就行~~
所谓的进程间通信,就是在隔离性的前提下,找一个公共的区域,让两个进程借助这个区域来完成数据交换
例:
比如说电视剧里的古代监狱里的重刑犯,你要吃饭,这时候你出不去,管理人员也进不去,这就是进程的隔离性,假如说你要吃饭,我就要给管理人员说,把饭放到放饭的台子上面,管理人进不去,我也出不去,这个放饭的台子,就是公共空间,这样的话就完成了进程间的通信;
就是在隔离性的前提下,做了个小小的妥协,这个妥协的功能,对大的结果没有影响下,就完成了进程间通信;
操作系统的提供的进程间通信具有多种实现方式,管道,消息队列,共享内存,信号.....但是他们的本质都是借助一个公共区域,完成数据交换;
在java圈中并不是很鼓励多进程编程
在java圈中主要使用 文件, socket 这两种方式来完成进程间通信;
进程是比较“重量级”的(速度慢,消耗资源多)
创建一个进程,成本比较高,销毁成本也高,调度也高....多进程编程可以解决并发编程的问题,但并不是一个高效率的选择
进程这么重量,主要就是体现在资源的分配上,资源分配往往是一个耗时的操作
比如:
系统要给进程分配一块内存
1.系统就需要遍历自己的空闲内存的表(数据结构)找到一个大小差不多的空间,进行分配~
2.很多个进程都在问系统申请资源,系统进行资源分配的时候,得一个一个来
线程 则是更轻量的进程 (轻量级进程)
四、线程
一个进程中可以包含多个线程,此时这多个线程,每个线程都是一个独立可以调度执行的“执行流”,(这些执行流之间本身就是并发的)
同时这些线程公用同一份进程的系统资源
-------------------------------------------------------------------------------------------------------------------------
一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。
进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程。一个线程不能独立的存在,它必须是进程的一部分。一个进程一直运行,直到所有线程都结束运行后才能结束。
这就意味着:对于线程而言,系统资源是已经分配好了的,创建线程就省下了分配资源的开销;
【总结】:
1.所谓的调度就是进行时间管理
进程的调度,其实就是操作系统在考虑CPU资源如何给各个进程分配--
由于操作系统上,同时运行多个进程,此时如果某个进程出现BUG,进程崩溃了,是不会影响其他进程的,因为进程之间通过虚拟地址空间,已经各自隔离开了,但实际工作中进程之间还是需要相互交互的。
2.虚拟地址空间:
在现代操作系统中,每个进程都有自己的虚拟地址空间,这使得进程可以独立地运行,而不会互相干扰或访问对方的内存。
虚拟内存地址的出现解决了内存管理中多道程序并发执行的问题,使得每个进程都可以享有连续的内存地址空间,并且不会因为其他程序的存在而受到影响。同时,虚拟内存也提供了更好的进程保护和安全性,可以保证操作系统和应用程序之间的隔离。
3.进程间通信
就是在隔离性的前提下,做了个小小的妥协,这个妥协的功能,对大的结果没有影响下,就完成了进程间通信;
4.线程
进程相当于工厂;
线程则是工厂中的流水线;
如有不足,请多指教,谢谢