计算机是如何工作的
计算机是如何工作的
cpu:
核心数:一个CPU中的核心数 在任务管理器中可以查看 核心数越多证明可以同时处理进程数就越多 并发执行效率就越高 还有就是 每一个核心也分单线程和多线程 有些核心单线程 可以理解成 只能干一份活 多线程可以理解成 一个人可以顶几个人 所以很多 cpu 会出现 12核 20 线程 证明这里面 有一些核心是 多线程一些是单线程的
通过编程 中引入的一些特殊方式 ,来把多个 cpu 给利用起来(并发编程)
主频:(单个核心的运算能力)他表示的意思是 1s 之内 cpu 所能执行指令的个数
- 基准频率:cpu最低的频率 最低速度
- 睿频:根据当前任务的繁忙程度 来 动态调整的一个数值 不能一直往上有一个 指标
指令:
我们写的代码就是指令,会被编译成 机器语言 最终由cpu去执行
要执行的指令会 被 加载到 内存中
结论:
-
CPU 要执行指令,实在内存中的 (冯诺依曼体系结构,基本设定:让执行单元和存储单元 解耦合)
-
CPU 要想执行指令 ,就需要先 取指令 再解析指令 然后才是 执行指令
-
取指令需要从 内存中读取指令到 cpu的寄存器中
也就是说 指令一开始是 存储在 内存之中的
取指令的操作是 很耗时间的 (读取内存操作相对于 cpu 执行计算 要开销大很多)
为什么呢? 因为每次 读取指令之后 要重新放回 内存中去 下次要使用的时候 要再次进行读取
因此 cpu 中通过缓存,流水线等技术来优化这里的效率
也就是 把 重复用到的指令 放在 缓存中去 下次方便调用 (简单理解)
-
cpu 解析指令的时候,需要用到 “指令表”,不同架构的 cpu 支持的 指令表是不一样的(X86和arm等都是不同的)指令表细节已经写死在 cpu 中 ,cup是很容易进行识别的
-
指令在执行的过程中,可能会带有一些 操作数,不同的指令,操作数的个数含义都有所不同
操作系统(软件)
它的主要作用有两个分别是:(抽象、封装)
-
管理各种硬件设备
外设,显卡,硬盘之类的
牌子种类繁多 不可能说一个一个去写代码 ,操作系统要做的就是 把 这些抽象封装起来 让他们去调用一些api 来实现 对 硬件的操作
-
给软件提供稳定的运行环境
目前比较主流的系统有:
windows、Linux、Mac、Android、IOS
进程 / 任务
操作系统所提供的一些 软件资源
上面就是一些 目前正在使用的 进程
可以看到 我们的系统是 同时进行多个进程的 ”多任务操作系统“
在第一张图中 我们可以看到 计算机的每一个进程/任务 在执行过程中 都会消耗一些硬件资源
每一个进程在运行的时候都要给他 分配一定的资源
进程 是系统分配资源的基本单位
操作系统如何管理进程呢
-
先描述 (使用类/结构体这种方式 把实体属性列出来)
表示进程信息的结构体又叫 PCB
就是说 操作系统将 进程的属性 都放到了 叫做 PCB 的结构体当中
-
再组织(把 PCB 通过一些数据结构的方式 串联起来)
这里比如 Linux 就是通过类似于链表的数据结构 把若干个 结构体 串联起来了
- 当 我们看到任务管理器的进程的时候 ,说明系统内部在遍历这个数据结构 并且打印每个节点的相关信息
- 如果运行一个新的程序,就会在系统中多一个进程,构造多一个 PCB 这样的结构体 添加到链表上
- 如果一个运行中的程序退出了,就需要把 对应的 PCB 从链表中删除,并且释放 对应的资源
PCB 的一些 核心属性:
-
pid 进程的身份标识(类似于 身份证)
也可以理解成
antu_increment
自增系统会 保证 同一台机器 同一时间 每个进程的 pid 都是不一样的
-
内存指针
描述进程使用内存的资源情况
整个系统 内存就这么多 (16G)
每个进程 在执行前都会 进行申请
必须使用申请的内存
内存指针 会描述 这个进程都能使用哪些内存
进程也需要 知道 哪里存的是 指令 哪里存的是 数据
-
文件描述符表
进程需要访问 硬盘
进程想要操作文件 需要先 打开文件
让你的进程 在 问价描述符表中 分配一个表项 来 描述 文件的相关信息
-
状态
描述 某个进程 是否能够去 cpu 上执行
就绪状态:随时准备好去 cpu 上执行
堵塞状态:这个进程 当前不方便去 cpu 上执行(比如 进程在等待 IO,来自控制台的输入输出/来自硬盘的输入输出......)
-
优先级
多个进程等待系统的调度
先调度谁 后调度水
系统api 可以进行设置的
比如 电脑运行 APEX 和 QQ
此时的 APEX 优先级更高
-
记账信息
针对每个进程,占据多少 cpu 空间进行一个统计
根据这个统计结果来 进一步的调整策略
确保每个进程都不至于出现完全捞不着CPU的情况
-
上下文
支持进程调度的重要属性
相当于游戏中的 读档 和 存档
前提:每个进程在运行过程中 都有可能运行到一半 被cpu 调度走了
存档: 因此 就需要在 进程调度出去之前 把当前寄存器中的信息 单独存放在一个地方
读档:在该进程下次进入 cpu 上执行的时候 我们再把这些寄存器的信息 恢复
“保存上下文” : 把 CPU 的关键寄存器中的数据 保存在内存中
“恢复上下文” : 把 内存中 关进啊寄存器的数据 加载到 CPU 的对应寄存器中去
CPU 与 进程
一个 进程,会消耗 CPU 的资源
理解:
CPU 是一个舞台 进程要执行指令 那就是演员
演员 需要 登上舞台 才能进行表演(工作)
同一时刻 ,一个舞台上,只能有一个演员
同一时刻,一个CPU上,只能执行一个进程
我的电脑是 8个逻辑核心
但是系统的进程 远远不止 8个
如何进行协调 :分时复用
分时复用:让 演员 轮流登台
cpu核心只有一个的情况下 :先执行进程1 执行一会之后,让1下来 执行进程2
进程2 执行一段时候后 下来 让进程3 .......
只要切换速度够快 ,人是感知不到切换过程的
在人眼看来就是 同时进行
鼠标转圈 就是 进程没捞进去cpu上执行 卡住了
如果是 多个 cpu 就会变得比较复杂了
同时可以 有 四个不同的进程 在各自的cpu上进行执行
这些是 真的 同时进行的 这种又叫 “并行执行”
当代的计算机 都是 并行和并发 同时存在的
“并行” 和 “并发” 统称为”并发“
解决一个问题 同时搞多个任务 同时执行 共同协同 统称为 :并发编程
内存管理
进程如何管理内存?
核心结论:
每个进程的内存都是 彼此相互独立的 互不干扰的
为了系统的稳定性
通常情况下,进程A 是不可以 直接访问进程B的内存的
进程间通信
虽然相互之间有独立性 但是有时候也需要,多个进程进行配合 完成某个工作
系统会 提供一些 公共的空间 让两个进程借助这种 公共的空间来交互数据
- 管道
- 共享内存
- 文件
- 网络
- 信息量
- 信号
其中 文件 和网络 是我们java程序员 最之遥的进程间通信方式
其中 网络 可以支持 同一个主机的不同进程,也能支持不同主机的不同进程