IO model

IO模型 
所有的IO操作都分为两个阶段,等待就绪和操作
阻塞   应用进程 recvfrom 系统调用 直到内核数据包准备好 将数据从内核拷贝用户空间 整段时间都是被阻塞的
非阻塞 应用进程 recvfrom  轮询调用 检查内核数据包是否准备好 将数据拷贝到用户控件的过程是阻塞的
IO复用 linux 2.6以前提供的select/poll 可以侦测多个fd 是否处于就绪状态 是顺序扫描而且支持数量有限 2.6之后的epoll 是基于事件驱动机制代替顺序扫描 当fd就绪时,立即回调windows是IOCP
信号驱动  当数据准备就绪时,为进程生成一个SIGIO信号,通过信号回调通知应用程序调用 recvfrom来读取数据,并通知主循环函数处理数据。
异步IO 告知内核启动某个操作,并让内核操作完后通知我们。和信号驱动的区别是,信号驱动通知我们合适开始一个IO操作,异步IO通知我们操纵已经完了,
所以也有人总结 已读操作为例,BIO最关心我要读(一直等待着) NIO 我可以读了(一直询问直到回应可以读),AIO 我读完了(读完通知)

BIO(传统IO)
同步阻塞IO,针对网络IO服务器端的实现是一个请求一个线程,客户端发送的请求通过创建线程来进行处理,就是因为此函数能造成线程阻塞,所以开了多条线程,充分利用CPU,可以用线程池改善此情况。
NIO
同步非阻塞IO,所有的连接请求都注册在多路复用器上,select是阻塞函数,多路复用器轮询是否有IO操作,有的时候会开启一个线程来处理,select poll会轮询 epoll
AIO
异步非阻塞IO,用户进程只需要发起一个IO操作就立即返回,等IO操作真正完成后,应用程序会得到IO操作完成的通知,此时用户进程只要对数据进行处理就好,不需要进行IO的读写操作
,因为真正的IO的读写操作已经交给OS内核完成了。
IO和NIO的区别?
1、面向流和面向缓冲
这是最大的区别,IO面向流意味着每次读取都是读取完所有的字节,没有被缓冲到任何地方,不能前后移动流中的数据。NIO是数据读取到一个稍后处理的缓冲区,需要时可在缓冲区前后移动。
2、阻塞与非阻塞
IO的各种流是阻塞的,在read和write时,线程被阻塞,知道有一些数据被读取,或者完全写入。线程在此期间不能再干任何事情了。
NIO在读的时候如果没有可用数据,线程什么都不会获取,不是保持阻塞,直至数据变得可读取之前,该线程可以做其他的事情。
3、NIO有选择器

为什么要选用NIO?
说明下BIO的主要弊端是线程的使用上,而线程是很贵的资源,主要表现在
1、线程的创建和销毁成本很高,在linux系统中线程本质就是进程,线程的创建和销毁都是重量级的系统函数
2、线程本身占用内存,例如JVM中的虚拟机栈中的线程一般分配512k,如果线程过多会吃掉JVM一大半的内存
3、线程的切换成本很高,OS在线程切换的时候,需要保留上下文信息,然后进行系统调用,如果线程数过多,线程切换的时间远远大于线程执行的时间,带来系统load偏高,CPUsy使用率特别高,导致系统陷入不可用状态。
4、锯齿状的线程负载,大量的请求阻塞后处理完同时被激活,从而使系统负载压力过大。

评论已关闭。