了解一些基本概念:
同步与异步:(主要是针对多个任务或者事件)
同步:如果有多个任务或者事件要发生,这些任务或者事件必须逐个地进行(单线程),一个事件或者任务的执行会导致整个流程的暂时等待,这些事件没有办法并发地执行;
异步:如果有多个任务或者事件发生,这些事件可以并发地执行(多线程或者多进程),一个事件或者任务的执行不会导致整个流程的暂时等待。
阻塞与非阻塞:(主要针对单个任务或者事件)
阻塞与非阻塞主要是从 CPU 的消耗上来说的,阻塞就是 CPU 停下来等待一个慢的操作完成 CPU 才接着完成其它的事。非阻塞就是在这个慢的操作在执行时 CPU 去干其它别的事,等这个慢的操作完成时,CPU 再接着完成后续的操作。
虽然表面上看非阻塞的方式可以明显的提高 CPU 的利用率,但是也带了另外一种后果就是系统的线程切换增加。增加的 CPU 使用时间能不能补偿系统的切换成本需要好好评估。
BIO、NIO、AIO的基本定义与类比描述:
BIO (Blocking I/O):同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。这里使用那个经典的烧开水例子,这里假设一个烧开水的场景,有一排水壶在烧开水,BIO的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。
NIO (New I/O):同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。
AIO ( Asynchronous I/O):异步非阻塞I/O模型。异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开水中就是,为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。
进程中IO调度分为以下几步:
1.进程向操作系统请求数据。
2.操作系统将外部数据加载到内核缓冲区。
3.(操作系统还是用户进程)将内核缓冲区的数据拷贝到进程缓冲区。
4.进程获得数据完成功能。
在进行2.3步的过程中,用户进程发生IO请求,再转交给内核,轮询内核数据是否就绪,操作系统通知用户进程未就绪,用户进程选择等待,就是同步阻塞的过程。
同样的,如果这样一个过程,当用户线程发起read操作之后,立刻就可以开始去做其它的事, 而另一方面,从内核的角度,当它受到一个asynchronous read之后,它会立刻返回,说明read请求已经 成功发起了,因此不会对用户线程产生任何block。然后,内核会等待数据准备完成,然后将数据拷贝到用 户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它read操作完成了。也就说用户线程 完全不需要实际的整个IO操作是如何进行的,只需要先发起一个请求,当接收内核返回的成功信号时表示IO 操作已经成,可以直接去用户空间使用数据了。而且在3步中,这个内核缓冲区拷贝到进程缓冲区的过程是由操作系统来帮忙完成的。所以异步非阻塞这样的模型是需要底层操作系统来提供支持的。
以上是java中IO模型
还有Linux中的五种IO模型