libuv 是一个多平台支持库,专注于异步 I/O。
它主要是为 Node.js 开发的,但也被 Luvit、Julia、pyuv 等使用。
功能亮点
由 epoll、kqueue、IOCP、事件端口支持的全功能事件循环。
异步 TCP 和 UDP 套接字
异步 DNS 解析
异步文件和文件系统操作
文件系统事件
ANSI 转义码控制的 TTY
带套接字共享的 IPC,使用 Unix 域套接字或命名管道 (Windows)
子进程
线程池
libuv 是一个多平台支持库,专注于异步 I/O。
它主要是为 Node.js 开发的,但也被 Luvit、Julia、pyuv 等使用。
由 epoll、kqueue、IOCP、事件端口支持的全功能事件循环。
异步 TCP 和 UDP 套接字
异步 DNS 解析
异步文件和文件系统操作
文件系统事件
ANSI 转义码控制的 TTY
带套接字共享的 IPC,使用 Unix 域套接字或命名管道 (Windows)
子进程
线程池
Java NIO是java 1.4之后新出的一套IO接口,这里的的新是相对于原有标准的Java IO和Java Networking接口。NIO提供了一种完全不同的操作方式。
Java NIO使我们可以进行非阻塞IO操作。
比如说,单线程中从通道读取数据到buffer,同时可以继续做别的事情,当数据读取到buffer中后,线程再继续处理数据。写数据也是一样的。
位于 java.nio
包下。
定义缓冲区,缓冲区是数据的容器,并提供其他NIO包的概述。
NIO api的中心抽象是:
我接触到 nio,最先的应用就是 Path 这个类。
最直观的感觉就是 api 设计的很优雅(相对于传统的 File)。
Java的path接口是作为Java NIO 2的一部分是Java6,7中NIO的升级增加部分。
Path在Java 7新增的。
相关接口位于java.nio.file包下,所以Javaz内Path接口的完整名称是 java.nio.file.Path
.
path可以指向文件也可以指向目录。可以使相对路径也可以是绝对路径。
绝对路径包含了从根目录到该文件(目录)的完整路径。相对路径包含该文件(目录)相对于其他路径的路径。相对路径听起来可能有点让人头晕。但是别急,稍后我们会详细介绍。
Java 暂时支持如下的标准编码
US-ASCII: 7位ASCII字符。
ISO-8859-1: ISO拉丁字母
UTF-8:这是8位UCS转换格式。
UTF-16BE:这是16位UCS转换格式,字节顺序大
UTF-16LE:这是16位UCS变换,以字节顺序表示。
UTF-16: 16位UCS转换格式。
Java NIO Channel通道和流非常相似,主要有以下几点区别:
通道可以读也可以写,流一般来说是单向的(只能读或者写)。
通道可以异步读写。
通道总是基于缓冲区Buffer来读写。
Channel 的实现(Channel Implementations)
下面列出Java NIO中最重要的集中Channel的实现:
Java NIO Buffers用于和NIO Channel交互。正如你已经知道的,我们从channel中读取数据到buffers里,从buffer把数据写入到channels.
buffer 本质上就是一块内存区,可以用来写入数据,并在稍后读取出来。
这块内存被NIO Buffer包裹起来,对外提供一系列的读写方便开发的接口。
利用Buffer读写数据,通常遵循四个步骤:
把数据写入buffer;
调用flip();
从 Buffer 中读取数据;
调用 buffer.clear() 或者 buffer.compact()
Selector是Java NIO中的一个组件,用于检查一个或多个NIO Channel的状态是否处于可读、可写。
如此可以实现单线程管理多个channels,也就是可以管理多个网络链接。
用单线程处理多个channels的好处是我需要更少的线程来处理channel。
实际上,你甚至可以用一个线程来处理所有的channels。从操作系统的角度来看,切换线程开销是比较昂贵的,并且每个线程都需要占用系统资源,因此暂用线程越少越好。
需要留意的是,现代操作系统和CPU在多任务处理上已经变得越来越好,所以多线程带来的影响也越来越小。
一个Java NIO的管道是两个线程间单向传输数据的连接。
一个管道(Pipe)有一个source channel和一个sink channel。
我们把数据写到sink channel中,这些数据可以同过source channel再读取出来。
第一步,应该弄明白,有哪些IO模型,它们的区别是什么。
第二步,要搞清楚,这些IO模型的缺陷是什么,在高并发的情况下,为什么阻塞式接口 + 多线程会遇到瓶颈:
第三步,解决方案就是IO多路复用,要搞清楚,Java的多路复用不过是操作系统相关调用的封装。比如 select / poll / epoll / kqueued 等等。
第四步,掌握 selector 的用法,然后JDK源代码就变得很清楚了。通过查看JDK源代码,可以验证上一步的结论:
第五步:外围与之相关联的东西看看就好,像FileChannel, DirectBuffer等比较特殊的地方,花点心思去看看就好了,这就不重要了。
零拷贝(Zero-copy)技术指在计算机执行操作时,CPU 不需要先将数据从一个内存区域复制到另一个内存区域,从而可以减少上下文切换以及 CPU 的拷贝时间。
它的作用是在数据报从网络设备到用户程序空间传递的过程中,减少数据拷贝次数,减少系统调用,实现 CPU 的零参与,彻底消除 CPU 在这方面的负载。
实现零拷贝用到的最主要技术是 DMA 数据传输技术和内存区域映射技术:
零拷贝机制可以减少数据在内核缓冲区和用户进程缓冲区之间反复的 I/O 拷贝操作。
零拷贝机制可以减少用户进程地址空间和内核地址空间之间因为上下文切换而带来的 CPU 开销。