网络模型总结

常用的五种网络IO模型是阻塞I/O,非阻塞I/O,I/O复用,事件(信号)驱动I/O,异步I/O。
为什么要发起系统调用?因为进程想要获取磁盘中的数据,而能和硬件打交道的只能是内核,进程通知内核说我要磁盘中的数据,此过程就是系统调用。
一次I/O的完成的步骤:当进程发起系统调用时,这个系统调用就进入内核模式,然后开始I/O操作。I/O操作分为两个步骤;
1、磁盘把数据装载到内核的内存空间,
2、内核的内存空间的数据copy到用户的内存空间中(此过程是I/O发生的地方)
以下是进程获取数据的详细图解过程;
avatar
整个过程:此进程需要对磁盘中的数据进行操作,则会向内核发起一个系统调用,然后此进程,将会被切换出去,此进程会被挂起或者进入睡眠状态,也叫不可中断的睡眠,因为数据还没有得到,只有等到系统调用的结果完成后,则进程会被唤醒,继续接下来的操作,从系统调用的开始到系统调用结束经过的步骤:
①进程向内核发起一个系统调用,
②内核接收到系统调用,知道是对文件的请求,于是告诉磁盘,把文件读取出来
③磁盘接收到来着内核的命令后,把文件载入到内核的内存空间里面
④内核的内存空间接收到数据之后,把数据copy到用户进程的内存空间(此过程是I/O发生的地方)
⑤进程内存空间得到数据后,给内核发送通知
⑥内核把接收到的通知回复给进程,此过程为唤醒进程,然后进程得到数据,进行下一步操作
I/O发生的地方才会出现阻塞或非阻塞
阻塞:进程发起I/O调用,进程又不得不等待I/O的完成,此时CPU把进程切换出去,进程处于睡眠状态则此过程为阻塞I/O
阻塞I/O系统怎么通知进程?I/O完成,系统直接通知进程,则进程被唤醒

阻塞IO(blocking I/O)

在内核将数据准备好之前,系统调用会一直等待所有的套接字,默认的是阻塞方式。
avatar

非阻塞IO(noblocking I/O)

每次客户询问内核是否有数据准备好,即文件描述符缓冲区是否就绪。当有数据报准备好时,就进行拷贝数据报的操作。当没有数据报准备好时,也不阻塞程序,内核直接返回未准备就绪的信号,等待用户程序的下一个轮寻。但是,轮寻对于CPU来说是较大的浪费,一般只有在特定的场景下才使用。
avatar

IO多路复用

IO多路转接是多了一个select函数,select函数有一个参数是文件描述符集合,对这些文件描述符进行循环监听,当某个文件描述符就绪时,就对这个文件描述符进行处理。
avatar

异步IO(asynchronous I/O)

当应用程序调用aio_read时,内核一方面去取数据报内容返回,另一方面将程序控制权还给应用进程,应用进程继续处理其他事情,是一种非阻塞的状态。
当内核中有数据报就绪时,由内核将数据报拷贝到应用程序中,返回aio_read中定义好的函数处理程序。
avatar

阻塞、非阻塞,同步、异步

关于同步和异步
同步和异步其实指的是,请求发起方对消息结果的获取是主动发起的,还是等被动通知的。如果是请求方主动发起的,一直在等待应答结果(同步阻塞),或者可以先去处理其他的事情,但要不断轮询查看发起的请求是否有应答结果(同步非阻塞 )因为不管如何都要发起方主动获取消息结果,所以形式上还是同步操作。如果是由服务方通知的,也就是请求方发出请求后,要么在一直等待通知(异步阻塞),要么就先去干自己的事了(异步非阻塞),当事情处理完成之后,服务方会主动通知请求方,它的请求已经完成,这就是异步。异步通知的方式一般是通过状态改变,消息通知,或者回调函数来完成,大多数时候采用的都是回调函数。
关于阻塞和非阻塞
阻塞和非阻塞在计算机的世界里面,通常指的是针对IO的操作,如网络IO和磁盘IO等。那么什么是阻塞和非阻塞呢?简单的说就是我们调用了一个函数之后,在等待这个函数返回结果之前,当前的线程是处于挂起状态,还是运行状态,如果是挂起状态,就意味着当前线程什么都不能干,就等着获取结果,这就叫同步阻塞,如果仍然是运行状态,就意味当前线程是可以的继续处理其他任务,但要时不时的去看下是否有结果了,这就是同步非阻塞。