- 阻塞IO模型
用户发出IO请求后,内核去查看数据是否就绪,如果没有就等待数据就绪,用户线程进入阻塞状态,交出CPU。
数据就绪后,内核将数据拷贝到用户线程,用户线程才解除block状态。
data = socket.read();
- 非阻塞IO模型
不需要等待,立马返回while(true){ data = socket.read(); if(data!= error){ } }
-
多路复用IO模型
使用较多,如Java中NIO. 在该模型中,会有一个线程不断轮询多个socket的状态.只有真正有读写事件时, 才真正调用实际IO读写操作.
在Java NIO中,是通过selector.select()去查询每个通道是否有到达事件.如果没有事件,则一直阻塞。 多路复用IO比较适合连接数比较多的情况。 多路复用的效率高是因为在非阻塞IO中,不断轮询socket状态是通过用户线程进行的,而多路复用IO轮询是 在内核中进行,这个效率更高。 - 信号驱动IO
在信号驱动IO模型中,当用户线程发起一个IO请求操作,会给对应的socket注册一个信号函数,然后用户 线程会继续执行,当内核数据就绪时会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函 数中调用IO读写操作来进行实际的IO请求操作。这个一般用于UDP中,对TCP套接口几乎是没用的,原因是 该信号产生得过于频繁,并且该信号的出现并没有告诉我们发生了什么事情。 - 异步IO模型
异步IO模型才是最理想的IO模型,异步IO模型中,当用户线程发起read操作之后,立刻就可以开始去做其 它的事。而另一方面,从内核的角度,当它受到一个asynchronous read之后,它会立刻返回,说明read 请求已经成功发起了,因此不会对用户线程产生任何block。然后,内核会等待数据准备完成,然后将数据 拷贝到用户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它read操作完成了。也就说 用户线程完全不需要关心实际的整个IO操作是如何进行的,只需要先发起一个请求,当接收内核返回的成功 信号时表示IO操作已经完成,可以直接去使用数据了. 异步IO是需要操作系统的底层支持,在Java 7中, 提供了Asynchronous IO。简称AIO。