huangzonggui 2020-06-04
程序进行IO读写依赖于操作系统底层的IO读写,主要为read、write两大系统调用。在不同的操作系统中,IO读写的系统调用的名称可能不完全一样,但是基本功能是一样的。
首先我们必须要明白的的是,read系统调用,并不是直接从物理设备把数据读取到内存中;write系统调用,也不是直接把数据写入到物理设备。上层应用无论时调用操作系统的read,还是write都会涉及缓存区。即,调用read,是把数据从内核缓存区复制到进程缓存区,wirte是把数据从进程缓存区复制到内核缓存区。
所以,程序的IO操作实际上是缓存的复制,并不是实际物理设备的读写,这项底层的读写交换,是由操作系统内核(Kernel)来完成的。
操作系统基础知识:
1.操作系统与外部设备之间:主要通过中断机制来实现。
2.操作系统与上层应用程序:主要通过异常与系统调用两个机制来实现。
缓存的目的是减少频繁地与设备之间的物理交换,因为外部设备的直接读写,都需要操作系统中断,而中断耗时耗力,所以缓存很有必要。
用户程序的IO读写程序,在大多数情况下,并没有进行实际的IO操作,而是在进程缓冲区和内核缓冲区之间直接进行数据的交换。
到这里,还是需要举个例子:
比如在Java服务器端,完成一次socket请求和响应,完整的流程如下:·
阻塞IO指的是需要内核IO操作彻底完成后,才返回到用户空间执行用户的操作。
同步IO指的是用户空间的线程是主动发起IO请求的一方,内核空间是被动接收方。异步IO则反过来,是指系统内核是主动发起IO请求的一方,用户空间的线程是被动接受方。
非阻塞IO,指的是用户空间的程序不需要等待内核IO操作彻底完成,可以立即返回用户空间执行用户的操作,即处于非阻塞的状态,与此同时内核会立即返回给用户一个状态值。
简单来说:阻塞是指用户空间(调用线程)一直在等待,而不能干别的事情;非阻塞是指用户空间(调用线程)拿到内核返回的状态值就返回自己的空间,IO操作可以干就干,不可以干,就去干别的事情。
注意:这里所说的NIO(同步非阻塞IO)模型,并非Java的NIO(New IO)库。
IO多路复用可以解决非阻塞IO模型中存在的轮询等待问题。