多线程、cpu本质原理

最近研究学习了一下汇编语言和操作系统原理,明白了疑惑多年的问题。

1、操作系统如何实现多进程、多线程。

2、cpu基本结构,cpu如何和其他设备(网卡、显卡、声卡、磁盘、usb)通信。

3、java虚拟机原理。

4、多线程的安全问题的本质原因。

 

下面一一记录,本人文学水平有限,大多都是口水话,勿怪。

 

1、目前的计算机体系都为冯罗伊曼(图灵、冯罗伊曼、哈佛结构的具体区别请自行百度)模型,包括输入和输出、运算、控制、存储。哈佛结构对冯罗伊曼结构的存储部分进行了细化,将存储分为数据区、代码区,这样便把程序和数据分离开来。

现代计算机由 cpu、存储器(Ram、Rom、磁盘、U盘、软盘等)、输入输出组成,cpu又可大致分为:控制器、运算器、存储器(寄存器)三部分。当然基本体系中还需要和外界进行通信,比如磁盘、显卡、网卡等设备。cpu做的事很简单,说简单,不是说cpu简单,而是说cpu没有达到人的思维,它只是进行简单的加法操作(cpu不能进行减、乘、除操作,所有运算都是通过加法操作转变,具体转变过程,请百度)、访问内存,将位于内存中的某个位置的数,读到cpu的ax寄存器(或其他寄存器),再把另一个数读到cpu的某个寄存器中,再由运算器进行运算,最后把结果存储到其他位置,或暂时存放到寄存器中。

2、再说说计算机如何运行起来的。

还是像上面一样,先说结构,再说流程。跟计算机运行相关的存储有 RAM(随机访问存储器,cpu访问哪个内存位置的数据的速度都是一样的)、ROM(只读存储器,计算机启动的时候,就会先从ROM中读取程序指令执行)、寄存器。

当按下开关那一刻,cpu就开始执行指令,永远都不能让cpu饿着,由于RAM存储器是掉电就会丢失数据,所以开机的那一刻cpu不可能从RAM中读取指令,而是从只读存储器ROM中读区指令。ROM的内存一般比较小,其中只是包括基本的开机必要指令以及bios(base input output system,基本输入输出系统的指令程序),剩下的就是从磁盘或u盘等外部设备中读取数据到RAM存储器中,从此以后计算机便运行起来了。

cpu能做的事情很“很简单”,说简单不是说cpu构造简单,而是相对于人的大脑来说,cpu做的事很淳朴。cpu能做的就是从内存(或磁盘设备、键盘、鼠标、网卡等外部设备)的某个位置的数据进行加法运算后,存到另一个地方。比如,mov ax,[es:0x0343]    该汇编指令实现的功能就是 从es:0x0343 偏移内存处的数值,转移到ax寄存器中。具体一点的流程是:cpu通过总线对内存发出:“我要ex:0x0343 处的数据”,RAM存储器(只是一个普通的外部设备),得到cpu发出的指令后,经过漫长的时间(相对cpu的执行速度而言),把ex:0x0343处的数据,转移到cpu的 ax寄存器中。当cpu执行完这条指令后,IP寄存器就会指向下一条指令(ip寄存器中存储的就是指令的地址,cpu每执行完一条指令,ip寄存器就会指向下一条指令,如此循环)。

 

3、从上面可以看出,cpu等外部硬件设备并没有多进程(多线程、多任务)的概念,只是简单的一条一条的执行机器指令。那么多进程是怎么实现的呢,那就是操作系统的功劳。在介绍多进程之前,先简单说说 cpu的两个时代,实模式、保护模式。个人认为实模式和保护模式的主要区别在于对内存的管理上,实模式时代,程序可以对整个计算机中的所有内存进行访问可读写,而用户模式时代,用户程序只能操作操作系统分配给程序的内存(通过GTD,全局描述符,分段机制来对内存进行管理控制)。扯远了,不管是windows系统还是linux系统,对多进程的实现原理大致相同,以windows系统为例,windows将所有程序放在一个就绪队列中,该队列 中的每个节点存储了每个进程的基本信息,包括cpu寄存器状态(ip、sp、sb、基本寄存器等等各种寄存器的状态)。windows系统通过一些算法,每100或几百纳秒,就从就绪队列中去除一个程序,并把该程序中记录的寄存器状态赋予个cpu的真实寄存器中,此过程需要耗费一些无用功,因为cpu在这个过程中干的活儿,对程序一点用处也没有,只是恢复该程序的运行状态,然后运行几百纳秒(具体多长时间,不太清楚)。从cpu的这个切换过程,也能大致明白,为什么会有NIO、AIO等概念,其目的就是减少cpu在切换程序或叫任务过程中的无用功。

 

4、java虚拟机,个人的猜想和理解,其垃圾回收机制是系统线程,new Thread().start() 启动的线程应该是java虚拟机模仿操作系统实现的多线程,所以叫做用户级线程。每个java线程都会有自己的程序计数器(类似于IP寄存器)、帧栈等私有属性。java虚拟机通过轮询的方式切换执行每个线程的逻辑代码,切换过程需要做无用功。这也是为什么线程堵塞会浪费cpu资源的原因。线程堵塞的时候,代表该线程的数据结构(可能是一个队列,也可能是链表,还没来得急研究,后期补上),就会一直存在,而java虚拟机每几百或几千纳秒还得做一次无用切换,这便大大浪费了cpu运算资源。

 

 

5、外部设备。不管网卡、声卡、显卡、磁盘或是RAM,ROM、还是键盘都属于外部设备,想要和cpu合作干活,就得满足一些协议,协议不只是网络协议,设备和cpu之间也得商定一些协议。网卡、声卡、显卡等外部设备都有自己得RAM、ROM器件,可能还包括简单得运算器。这就是为什么挖矿(比特币等虚拟币)需要显卡优秀而不是cpu优秀得原因。cpu要读取键盘敲击的字符,一般流程如下:cpu发出键盘端口命令,“我要读取键盘中的敲击字符”,键盘得到指令后,如果有敲击时间,就会发送一个中断指令给cpu,并把字符相关信息,发送的 ax寄存器中。

 

6、中断。个人理解,cpu分两种中断,一种是不可忽略中断,比如3/0,除数为0,这中结果没有意义,cpu必须停止运行程序,处理这个错误结果,因为再继续运行,也没有意义,只是白白浪费cpu运算资源。或者是断电通知,当外部(不知道什么设备)对cpu发送断电信息通知时,cpu也得必须马上停止手上正在运行的工作,转而处理应对即将断电的事件。另一种是可屏蔽的中断事件。比如网卡发送一个中断给cpu,说“有新的网络信号”,cpu可能等到网络数据足够多的时候,再一并处理,而不是从网络环境中来一个字节,就停下手中正在处理的活儿,去处理网络数据,来一个又去处理。而是批量处理,以减少不必要的cpu状态,提高运行效率。

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值