计算机是如何工作的
1. CPU 2.主板 3.内存 4.硬盘 5.电源 6.散热器 7.机箱 8.显卡 9.键盘鼠标 10.显示器
冯诺依曼体系结构~一台计算机:1. CPU2.存储器3.输入设备4.输出设备
针对存储空间 硬盘>内存>>CPU
针对数据访问速度 CPU>>内存>硬盘
CPU中央处理器:进行算术运算和逻辑判断. 存储器:分为外存和内存,用于存储数据(使用二进制方式存储) 输入设备:用户给计算机发号施令的设备. 输出设备:计算机个用户汇报结果的设备.
1.内存读写速度快,硬盘读写速度慢 几千倍~~
机械硬盘读写速度 一般是200MB/s左右
内存,速度就快了,在刚才这个基础上几千倍水平~~
2.内存存储空间比较小,硬盘存储空间比较大3.内存的成本比硬盘更高(贵)
内存和硬盘 1.内存访问速度快,硬盘速度慢 2.内存空间小,硬盘空间大 3.内存成本高,硬盘成本低 4.内存数据掉电后丢失,硬盘数据掉电后持久存储
如果不差钱,完全可以搞一个大内存.
显卡-GPU和CPU是很相似的~~都能进行算术运算和逻辑判断~~
显卡GPU成本大概占一台电脑的一半左右~
做个比喻:
CPU是一个大学生,能算1+1,也能算微积分."通用计算芯片" GPU是小学生,只能算1+1,算不了微积分~~ 一组小学生.虽然算不了微积分,如果是就算1+1 GPU速度比CPU快很多了.
GPU就是用来处理,运算虽然简单,但是运算量非常大的场景~~
图形渲染(大型游戏,3D建模)AI人工智能~~模型训练~~就是在算大量的1+1 使用显卡就非常合适~~
即使你的电脑只是核显(CPU自带的显卡,性能比较弱) 不影响学习编程~~
如果你是读研,你要研究AI相关,最好还是要有一个好的显卡~~
认识计算机的祖师爷--冯诺依曼 冯·诺依曼(John von Neumann,1903年12月28日-1957年2月8日), 美籍匈牙利数学家、计算机科学家、物理学家,是20世纪最重要的数学家之一。 冯·诺依夫曼是布达佩斯大学数学博士,在现代计算机、博弈论、 核武器和生化武器等领域内的科学全才之一,被后人称为"现代计算机之 父"、"博弈论之父"
计算机中,一个汉字占几个字节?
取决于字符集(汉字是怎样编码的)
CPU基本工作流程 CPU介绍
有的设备,既是输入设备,又是输出设备:触摸屏
网卡(上网的时候,和网线连接的那个部分对应的硬件设备)集成在主板上的~~
下载数据,输入
上传数据,输出看你的这个参照物是什么,一般来说是电脑主机,那么数据进入网卡,进入主机,是输入(即从云上下载数据)上传,数据从主机经过网卡,发出去,输出.
计算机使用二进制存储和表示数据~~
现代cpu的一个特性.动态的根据当前的任务量,频率变更.(类似于变频空调)
周围温差大,空调工作效率就高,快速降温(耗电量也大)1.cpu的频率 G就相当于10^9 10亿 GHz
最开始的cpu(2008年之前):之前的cpu都是单个核心的.当时研发新的cpu,就是努力提高cpu的频率~(intel)提高到一定程度,提高不上去了~~cpu内部构造非常精密.里面是由数不清的小的电路元件构成的计算单元
计算单元越多,算的就越快.
一个cpu面积是固定的.要想让计算单元多,单个计算单元就得小~~无限小??小到一定尺度~~经典的物理学就失效了
进入到量子力学范畴了为啥不把cpu面积变大一点??也是有的.服务器的cpu就会面积更大.面积不会大很多~~
(面积越大,生产过程中良品率就越低)当前cpu都是号称4nm制程,5nm制程,7nm制程
单个核心既然已经达到瓶颈,干脆引入两个核心来进行工作(多核心技术)
intel研发出了"超线程技术",让一个cpu核心,顶两个,cpu上就有4个核心
物理核心,真实干活的人
逻辑核心,实际上这些人能同时干几个活
目前,intel自费武功.从12代cpu开始,提出了"大小核"技术体系 大核,一个顶俩 小核,一个顶一个
6大核8小核
那CPU如果被换包了,这个资源管理器还是之前CPU指数,还是现在这个CPU的指数呢
你的主板上插的是啥cpu,显示的就是哪个cpu的 信息~~
内存地址~
内存,想象成一个宿舍楼,有一个长长的走廊,走廊上有很多的宿舍房间
就给每个房间都分配了一个门牌号.
从0开始,顺序的,连续的,依次累加~~
把这个房间的门牌号就称为"房间地址"=>"内存地址"
如果在C语言中,定义一个变量,保存上述内存地址
这个变量就称为"指针变量"
计算机中,一个汉字占几个字节? 取决于字符集(汉字是怎样编码的) gbk(中国大陆上曾经广泛使用的) windows10/11简体中文版默认gbk. 使用VS写代码打印汉字strlen,结果是2 一个汉字占2个字节. utf8(当下全世界最流行的编码方式) 一个汉字占3个字节.utf8本身是变长编码(1-4) unicode(Java的char就是使用unicode)一个汉字2字节
寄存器,也是存储数据的模块,是长在cpu身上的.
cpu存储数据,就是通过寄存器
cpu的寄存器,访问速度比内存还要快很多 存储空间也比内存小很多 成本也高很多
掉电之后数据也会丢失cache是介于寄存器和内存之间存储设施(也是集成在cpu上的)
cpu的寄存器 主要是在cpu进行执行指令 进行各种运算的时候 存储临时数据,起到一些辅助效果
CPU执行指令的流程
1.读取指令
2.解析指令(对照指令表,理解指令的含义)
3.执行指令把1110地址上的数据,读取到寄存器A中 14
最后执行指令
CPU默认的就是顺序的执行下一条指令
(如果遇到条件语句,循环语句,函数调用语句......)通过上述例子,能够明确几个概念:
1.指令2.寄存器3.cpu执行指令的大概过程后续学习多线程,理解线程安全问题
务必站在指令的角度 CAS等相关操作.....指令级别的操作后续工作中可能有这样的一个场景:
生产环境,你的服务器,有一个严重bug
但是现在服务器程序,还不能重启
如何给一个正在运行的程序进行修复bug???
这个操作就相当于给一个正在飞的飞机,修理发动机核心思路:热(不重启)补丁
一个服务器程序,本质上就是内存中的一段指令,cpu在执行这段指令完成各种功能找到出现bug的代码,对应在内存指令中的位置 然后把这个指令修改掉,
比如在这里插入一个跳转指令,让程序执行到这个指令的时候 跳转到内存中的另外一段(已经修复过bug)的指令进行执行~
程序
所谓程序,就是一组指令以及这组指令要处理的数据。狭义上来说,程序对我们来说就是一组文件。 程序=指令+指令要处理的数据。
进程
进程是操作系统对一个正在运行的程序的一种抽象,换言之,可以把进程看做程序的一次运行过程; 同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位。
进程是操作系统进行资源分配的最小单位,这意味着各个进程互相之间是无法感受到对方存在的,这就是操作系统抽象出进程这一概念的初衷,这样便带来了进程之间互相具备"隔离性
进程控制块
进程--pcb进程控制块--c语言写的操作系统
每一个PCB对象,就代表着一个实实在在运行着的程序,也就是进程。
pid进程 --进程的身份标识符
exe文件--可执行文件,双击创建进程--exe文件里面会包含二进制的指令
exe文件是程序员写代码的时候生成的。
存在指令+指令执行所依赖的数据--执行会加载到内存当中--
内存指针--进程需要知道执行的指令在哪里,指令依赖的数据在哪里
站在操作系统的视角,如何管理进程?
1.先描述出一个进程是啥样的 使用结构体,描述出进程的核心属性进程控制块(PCB) 非常大的结构体,有很多很多的属性
2.再把多个进程组织起来 比如,Linux这样的操作系统,使用链表这样的形式,把多个PCB串到一起的 不一定是一个链表
1)创建一个新的进程
创建一个PCB,初始化PCB中的各个属性 把PCB加到链表上
2)销毁一个进程
把这个进程的PCB在链表上找到,并且从链表上删除掉3)查看进程列表
遍历链表,取出链表上的每个元素--把里面的一些关键信息,显示到界面上
PCB中的一些关键要点
1.pid(进程id) 进程的身份标识符~~
2.内存指针双击exe,运行一个程序,创建一个进程
操作系统加载的过程.
可执行文件(保存在硬盘上的一段数据)
1)cctalk这个程序运行过程中,都要执行哪些指令(二进制的) 是程序员写代码生成的
exe 程序员写的代码,最终就被编译成二进制指令 包含在上述的exe中了~~
操作系统,会把exe中的指令和数据,读取出来加载到内存中
后续进程在运行过程中,就会从指令内存区域里一条一条的取指令并进行执行~~操作系统本身也是一个软件,也是由一系列指令构成的.cpu就会依次执行操作系统上的这些指
令(操作系统才跑起来)所有的软件本质上都是靠cpu来执行的cpu具体执行哪些指令,一定程度收到操作系统的影响
3.文件描述符表
进程,运行过程中,很多时候,需要和硬盘这个硬件设备,也去进行交互
硬盘上的数据,就是以文件的形式来组织的进程在读写文件的时候,就需要先"打开文件"fopen
每次打开一个文件,就会把这个文件的信息,保存到文件描述符表中
表里的每个项,就对应着一个打开了的文件
操作系统中,会把很多资源,都抽象成文件来表示,不一定是硬盘上的资源
网卡操作系统管理网卡的时候,就是当做"文件"一样来管理进程的运行,也会依赖到硬盘,网卡等相关的资源设备.
进程运行,执行指令,都是靠cpu的,进程也需要消耗cpu资源.
进程是操作系统中,资源分配的基本单位
PCB中的进一步的属性 进程调度
4.进程状态
5.进程优先级
6.进程的上下文
7.进程的记账信息操作系统进行进程管理过程中,完成的重要工作.
我的电脑上,进程有百八十个.但是电脑cpu的核心数12个
一个cpu逻辑核心,同一时刻,只能执行一个进程的指令
12个干活的cpu如何同时进行一百多个任务的工作??早期的计算机,操作系统,"单任务"操作系统.
同一时刻,只能运行一个进程.要想运行下一个进程,就得结束上一个进程多任务操作系统(在有多核处理器之前,多任务系统就已经有了)
即使cpu只有一个核心,也能同时运行多个进程. 分时复用
把一个单位时间,分成很多份. 第一份,运行进程1的指令 第二份,运行进程2的指令cpu运行速度足够快,上述的切换过程,也会非常快 快到超出人类的反应时间
使人看起来感觉好像这些进程在"同时执行"一样.
如果运行的任务实在太多了 人也是有可能感知到这个卡顿的过程
把一个CPU核心上,按照分时复用,执行多个进程这样的方式,称为"并发执行"
人看起来是同时执行,微观上,其实是一个CPU在串行执行,切换速度极快.
把多个CPU核心上,同时执行多个进程这样的方式,称为"并行执行" 就是"同时执行"
现代cpu在运行这些进程的时候,并发和并行是同时存在的.程序员,写代码的时候,无法区分当前这些进程是并行执行还是并发执行
"所以也会把并行和并发,统称为"并发"因为需要并发执行,所以操作系统需要进行进程的快速切换,也就是"进程调度"
4.进程状态
进程有很多状态,其中两个最典型的
1)就绪状态->随叫随到 进程就可以随时到cpu上进行执行 在操作系统中,一般不区分就绪和执行 都是就绪2)阻塞状态->进程当前不适合到cpu上执行
5.进程优先级
这么多进程,他们能够去cpu上运行的机会是均等的嘛?
有些进程,就是要优先级更高一些,吃到更多的cpu资源.
6.进程的上下文
进程调度,一个进程执行一会,失去cpu.过了一段时间之后进程还会回到cpu上执行.
沿着上次执行到的状态,继续往下执行(而不能是重头执行)
进程在CPU中运行的过程中 CPU上的各种寄存器,就表示了当前进程运行的"中间状态"
保存上下文:把CPU中的这些寄存器的值,保存到内存中(PCB的对应属性中)
恢复上下文:把PCB中刚才保存属性,填写回对应的寄存器中.寄存器,不只是存储中间结果 也会存储当前这个进程执行到第几条指令了
以及当前进程中"函数调用关系"一个cpu核心,一共才几十个寄存器. 一个寄存器,才存几个字节的数据
KB级别的存储空间
7.进程的记账信息
统计功能.统计每个进程都在CPU上运行了多久.
如果发现某个进程,好久没有吃到cpu资源了,就会给这个进程倾斜一些资源
进程 多任务操作系统 CPU是多核心 通过多进程编程的方式,可以实现"并发编程"效果进程整体是一个比较"重"概念. 创建进程/销毁进程开销比较大
(尤其是频繁的创建销毁)MySQL客户端-服务器结构的程序.
MySQL服务器,是保存数据的本体.
一个服务器程序,同一时刻,要给多个客户端提供服务 并发编程
多进程的方式,就是一种解决方案
每一个客户端请求发到服务器上,服务器提供一个进程,给这个客户端进行服务为了解决上述问题,引入线程(Thread),轻量级进程
每个进程,都相当于是一个要执行的任务
每个线程,也是一个要执行的任务(运行的一段代码指令)进程包含线程 每个进程中,都会包含一个或者多个线程
2.进程是操作系统资源分配的基本单位.
CPU,内存,硬盘资源(文件描述符表)....网络带宽
进程内部管辖的多个线程之间,会共享上述的内存资源和硬盘资源,网络带宽.....进程创建,需要申请资源
进程销毁,需要释放资源
对于线程来说只是第一个线程创建的时候(和进程一起创建的时候)申请资源.
后续再创建线程,不涉及到资源申请操作.(干的事少,快)
只有所有的线程都销毁(进程销毁)才真正释放资源
运行过程中销毁某个线程,也不会释放资源.进程和进程之间,所涉及到的资源则是各自独立的~~ 保证了稳定性 彼此之间互不干扰
一个进程内部的线程之间,是否会容易相互影响呢?确实如此!!!
也是学习多线程编程的最主要难点=>"线程安全问题"CPU资源,很难使用"共享'词来描述~~
CPU好比舞台.每个线程就是演员.每个线程都有去舞台上表演的机会
线程在cpu上执行的这一系列过程,和上节课讲的"进程调度"其实是一样的线程是CPU上调度执行的基本单位
如果一个进程包含多个线程
此时,多个线程之间,各自去cpu上调度执行的比如进程里有线程1,2,3
很有可能线程1去cpu核心1上执行,2去cpu核心2上执行,3去cpu核心3上执行(并行)也有可能,线程1,线程2,线程3在一个核心上 来回切换(并发)
也可能是线程1,线程2在一个核心上来回切换
线程3在另一个核心上,和别的进程的线程来具体这些线程是怎么调度执行,这个过程程序员,感知不到 也干预不了
全是由操作系统内部"调度器"自行完成的这一个进程,有10个线程,就有10份这样的数据
但是这10个线程,共用同一个文件描述符表和内存指针虽然提高线程的数目,能够提升效率.也不是"线性增长"
线程数目达到一定程度之后,就算线程再多,也没法起到效果了. 因为空间是有限的线程数目如果太多,线程的调度开销也会非常明显.
一个线程抛出异常,可能就会带走整个进程 所有的线程都无法继续工作.
如果及时捕获到,处理掉,也不一定导致进程终止