IO(一)
IO:Input和Output的缩写。在计算机中,CPU负责计算,数据则由管道进行传递,而对外传递的管道就是IO接口,上大学的时候学的是51单片机什么的,就会有很多的外接口,这些也是IO,IO可以是内存到硬盘的路,也可以是内存到外部设备的路。
比如你打开浏览器,访问新浪首页,浏览器这个程序就需要通过网络IO获取新浪的网页。浏览器首先会发送数据给新浪服务器,告诉它我想要首页的HTML,这个动作是往外发数据,叫Output,随后新浪服务器把网页发过来,这个动作是从外面接收数据,叫Input。所以,通常,程序完成IO操作会有Input和Output两个数据流。当然也有只用一个的情况,比如,从磁盘读取文件到内存,就只有Input操作,反过来,把数据写到磁盘文件里,就只是一个Output操作。
就IO,I和O是一般离不开的,Java开发中读文件,需要I,写文件需要O。
随着科技的进步,带动了需求的进步,CPU的执行越来越快,而硬盘的速率陷入了瓶颈。就慢慢衍生出了异步IO(大概 这个的提出是因为CPU晶振的改进,然后Linux在某个版本的时候进行了异步IO的支持,慢慢推动了这项技术的实现)[具体原理],之后又慢慢的有了多路复用等概念,其实万变不离其宗。
一般提到IO会想到同步,异步,阻塞,非阻塞。然后有个2X2的组合。
这边的理解有很多层,有认为同步异步和阻塞非阻塞之间是两个不同的概念,也有认为是同义词的。准确的说
阻塞式发送(blocking send) 发送方进程会被一直阻塞, 直到消息被接受方进程收到。
非阻塞式发送(nonblocking send)。 发送方进程调用 send() 后, 立即就可以其他操作。
阻塞式接收(blocking receive) 接收方调用 receive() 后一直阻塞, 直到消息到达可用。
非阻塞式接受(nonblocking receive) 接收方调用 receive() 函数后, 要么得到一个有效的结果, 要么得到一个空值, 即不会被阻塞。
个人认为是一对同义词,同步自然会有阻塞的情况。
![](https://img2020.cnblogs.com/blog/1898491/202011/1898491-20201120134227987-1117266584.png)
具体的概念涉及到DPL和CPL与处理器之间的执行过程,往上一点说就是 中断,时钟中断,系统调用之间的关系。
从CPU的角度看,它的工作就是一直读取指令,然后执行。如果没有意外,这个过程会一直持续下去。
程序是由指令序列组成的,CPU执行某个程序时,就是读取对应程序的指令并执行(不太严谨)。如果没有意外,这个过程就不会中断,直到所有的指令都执行完。
linux是分时操作系统,就是CPU时间会分为多个时间片,比如10毫秒一个时间片,程序执行一个时间片之后,操作系统会重新选择一个任务来执行。问题是CPU是怎么知道时间片到了呢?又是如何触发任务选择的呢?
关键原理就是CPU有个外部时钟,这是一个倒数计时器,初始时会设置一个数字,比如1000,然后每个时钟脉冲数字减一,减到0的时候,就给CPU发一个信号,CPU会中断当前程序,来处理这个信号,这个信号的处理程序会重置计时器,并执行信号处理函数,如此反复,起到了时间分片的效果。
信号处理函数可能会重新选择另一个任务来执行,这个就是进程切换。
当然这些都需要CPU在硬件层级进行支持,比如可以接受外部中断信号,暂停当前任务,转去执行信号处理函数。然后操作系统会利用这种底层机制,做出分时功能。
OK到这边差不多就可以猜出同步和异步之间的流程了,异步=同步+哨兵。
这样说不太严谨,但是我个人认为可以这么概括。指令集--->操作系统--->CPU。
其实总体是一个复杂的事情
一条"Hello World"从写到编译到执行是一个很复杂的过程。
抄袭一个知乎的图,这个图可以很清晰的表示出代码执行的一系列过程。
CPU从存储器或高速缓冲存储器中取出指令,放入指令寄存器,并对指令译码。它把指令分解成一系列的微操作,然后发出各种控制命令,执行微操作系列,从而完成一条指令的执行。指令是计算机规定执行操作的类型和操作数的基本命令。指令是由一个字节或者多个字节组成,其中包括操作码字段、一个或多个有关操作数地址的字段以及一些表征机器状态的状态字以及特征码。有的指令中也直接包含操作数本身。
写到着我也不知道自己接下来要写什么了......
继续深入就是计算机原理了,往上就是应用层。