之前已经学过很多的知识,但是总会有一个疑惑,这些知识有什么用?
接下来的JavaEE的目标就是做出一个属于我们自己的网站
网站=前端+后端
简单来说,前端就是客户端,也就是浏览器运行的网页
后端就是服务器工作,也就是公司机房部署的程序
之后的学习将以后端技术栈为主,前端技术栈为辅进行学习
总的来说,执行程序过程:硬盘=>内存=>CPU=>解析指令=>执行指令
对于Java程序来说,由.java=>.class=>JVM读指令,解析指令,执行指令=>转换为CPU能认识的二进制指令
基础的门电路是与门 或门 非门
构造出了更复杂的电路,进一步构造出了加法器
操作系统是一种搞管理的软件
PC端: Windows linux MacOS
移动端: Android(本质上是linux) IOS
进程也叫做任务,一个跑起来的程序就被称为进程
.exe是可执行文件/可执行程序,它是存储在硬盘上的文件(静态的)
一旦双击,操作系统就会把这个文件的核心数据加载到内存中,同时在系统中生成一个"进程",可以在任务管理器上看到(ctrl + shift + esc)
只有双击可执行文件,才会产生进程,也就是说,要是单单只是一个可执行文件,就只是静态的,一旦运行起来,变成一个进程,执行程序里的指令,此时才是"动态的"
一个常见的误区:电脑上安装的程序太多了,电脑就会变卡
其实,硬盘上的可执行文件多了,只是占用硬盘空间,只要不双击运行,就不会占用内存空间,也不会占用CPU资源,根本不会影响到电脑, 至于电脑卡不卡,一般来说, 只有运行的程序多了,才会卡
还有一种情况,要是C盘快满了,会变卡 原因是很多的操作系统,在内存空间不够的时候,会使用一部分的硬盘空间,作为"交换分区",要是C盘(硬盘) 空间都不够了,就会影响到交换分区,就有可能会卡
操作系统是如何管理的?
描述的时候,是通过结构体来描述的,结构体里面包含一个进程的各种信息,这个结构体就叫做PCB(进程控制块)
描述的时候,系统通常会使用双向链表来把这些PCB组织起来
创建一个进程,本质上是创建一个PCB,并且加入到双向链表中
销毁一个进程,本质上是从双向链表中删除对应的节点
查看任务管理器的进程列表,本质上是在遍历这个双向链表
一个进程可能是一个PCB(进程管理块),也可能对应多个PCB
系统管理PCB的时候,也不一定只有一个PCB,可能会有多个PCB
进程里面有哪些关键的要素
一. pid 进程识别号 进程的身份标识
同一个主机,同一时刻,这些进程的pid是唯一的,可以通过pid来区分一个进程,但是进程终止的话,pid会被系统回收,可能会被继续分配给新运行的程序,所以pid是暂时唯一的
二.内存指针
要想创建进程,就要给进程分配内存空间,.有的用来存放数据.有的用来放指令,还有的用来维护运行状态… 内存指针就是确定那一块内存是放上什么的
三.文件描述符表
每个进程都会打开一些文件,文件描述符表就记录了当前进程打开了哪些文件
内存指针描述的是进程持有的内存资源
文件描述符表描述的是进程持有的文件资源
所以说进程是操作系统分配资源的基本单位
当CPU资源有限,就需要合理安排
多核CPU就是每个CPU核心上,都可以独立运行一个进程
并行执行:多个CPU核心,都可以同时独立的运行多个进程
并发执行:一个CPU核心,先运行进程1 ,再运行进程2 ,再运行进程3,只要微观上切换的够快,宏观上看就像是3个进程同时运行
所以进程调度就是通过"并行" 和 “并发”,让计算机同时执行多个进程,现在主流的操作系统都是多任务的
一.进程状态
进程状态分为五种: 运行状态 就绪状态 阻塞状态 创建状态 结束状态
阻塞状态的进程,无法被调度到CPU上执行
就绪状态的进程,才能带CPU上执行
二.进程优先级
系统调度的时候,就会根据优先级,来给进程进行时间安排
三.进程上下文
进程在CPU运行一会之后,要切换到别的进程,此时就要保存当前运行的中间结果(存档),下次再轮到它执行的时候,就恢复之前的中间结果(读挡),继续往下执行
对于进程来说,上下文就是CPU的寄存器的值,寄存器的值包括了运行的中间结果,需要将这些结果保存到PCB的上下文信息中(内存中) 也就是(寄存器–>内存)
四,进程记账信息
统计每个进程在CPU上执行了多久,起到辅助调度的效果,避免了有些进程优先级低的进程完全执行不了
进程1和进程2安排一下内存资源,一旦进程1出现内存访问越界,就会有可能影响到进程2,这是十分危险的
为了解决这个问题,就要让每个进程有各自的内存空间,不要让这些进程的活动范围重叠,这里给每个进程的内存空间就叫做"虚拟地址空间"(不是真实的物理内存地址)
会通过MMU(memory management unit )来完成虚拟地址到物理地址之间的映射
MMU映射的时候会进行检查,一旦有进程访问量更大的内存空间,MMU就会即使发现,避免了对物理内存产生影响
使用虚拟地址空间就可以使进程之间存在了"隔离性",这样子一个进程就不能直接访问另一个进程的内存数据, 一个进程出现bug,不会影响到别的进程 , 防止干扰的操作,提高了系统的稳定性
但是有些需求场景,需要多个进程相互配合,进程一旦隔离就很难交互,所以系统有引入了一个机制-------进程间通信
不管是哪种进程间通信,核心原则都是一样的 : 找一个多个进程都能访问到的公共资源,然后基于公共资源来交换数据
总结一下:
进程之间要求要有独立性(相互之间不影响) 通过MMU实现
进程如果需要进行配合通信,就需要使用特定的 进制间通信机制 (主要创是基于文件和基于socket(网卡))
创建进程的步骤:
- 创建PCB
- 给进程分配资源(内存/文件)资源,赋值到PCB中
- 把PCB插入到链表中
销毁进程的步骤
- 把PCB从链表上删除
- 把PCB上的资源释放
- 销毁PCB
创建和销毁进程最消耗资源的是第二步(对资源的分配),所以效率比较低
因此就出现了线程的概念(thread)
线程是包含在进程中的,一个进程默认会有一个线程,也可以也有多个线程,每个线程都是一个"执行流" , 可以单独的在CPU上进行调度,同一个进程的这些线程共通过使用同一份系统资源(内存资源/文件资源)
线程可以被称为是"轻量化进程",
创建线程的开销比进程小,销毁线程的开销比销毁线程小(有效地解决了创建/销毁进程的第二步的问题)
使用多线程的好处:
- 使用多线程能够充分利用CPU,能提高效率
- 创建第一个线程的时候,需要申请资源,后续再创建线程的时候,都是共用一份资源(节省了申请资源的开销)
- 销毁线程的时候,一直到销毁到最后一个线程的时候,才会真正释放资源,之前的线程销毁,不必真的释放资源(节省了释放资源的开销)
进程包含了线程,一个线程对应一个PCB,一个 进程对应一组PCB
在一组PCB上的内存指针和文件描述符表都是一样的(共用同一份资源)
而状态 上下文 优先级 记账信息则是每个PCB(每个线程)独有的
所以说进程是 资源分配 的基本单位 , 线程是 调度执行 的基本单位
进程与线程的区别(重中之重)
- 进程包含线程/ 线程是进程的一部分----明确关系
- 线程比进程更轻量,创建和销毁都更快-----快的特点
- 同一个进程的多线程之间共用同一份内存资源 文件资源,而进程之间是独立的内存/文件资源 ----解释为什么线程更快
- 进程是资源分配的基本单位 线程是调度执行的基本单位-----总结
举一个例子:
要是继续增加人数,效率就会更高,但是不是人越多越好,要是人超过一定的数量,反而会降低效率
对应到多线程上,线程数目也不是越多越好,CPU核心数是有限的,当线程达到一定成都的时候,CPU核心数已经被吃满了,此时再增加线程,也没法提升效率,反而会因为线程调度开销太大,降低效率