同步:应用自己进行IO读写
异步:内核完成IO读写,应用没有访问IO,回调程序只是读取访问Buffer而已
阻塞:BLOCKING 程序堵塞等待IO
非阻塞:NONBLOCKING 程序不堵塞,如果没有IO,会返回-1
组合:同步阻塞、同步非阻塞、异步非阻塞
多路IO通过一个系统调用,可以获得其中IO状态,然后有程序对自己敢兴趣的IO状态进程 *** 作。
基础中断 分类 selectselect函数需要遍历所有传入文件描述符的IO连接,只不过这个过程是由 *** 作系统内核完成的,只会触发一次系统调用。
select的IO中断响应只是把网卡数据通过DMA拷贝到select函数传入文件描述符的Buffer中。
传统的NIO这个遍历过程需要每次调用 *** 作系统内核完成查询IO状态,涉及到多次内核态用户态转换,系统执行效率底下。
Linux系统函数
poll函数需要遍历所有传入文件描述符的IO连接,只不过这个过程是由 *** 作系统内核完成的,只会触发一次系统调用。
epoll参考select
epoll系统函数,会在 *** 作中开辟一个系统空间,这个 *** 作空间是红黑树结构,内部维护了传入文件描述符集合,当有IO事件发生的时候,内核会将有IO状态发生的文件描述符拷贝到一个链表,应用程序只需要遍历这个链表就可以,无需遍历所有文件描述符,极大提升系统效率。
linux系统函数
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(9090));
serverSocketChannel.configureBlocking(false);
//linux多路复用器 select poll epoll
//打开Selector处理Channel
Selector selector = Selector.open();
//select,poll会在jvm里面开辟内存维护FD数组,epoll:elpoll_ctl添加到内核开辟的空间
//把ServerSocketChannel注册到Selector上,并且selector监听accept连接事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
select事件处理
while(true){
//它会阻塞等待需要处理的事件发生
selector.select();
//select,poll调用内核select(FDS),epoll调用epoll_wait
//获取selector感知到的事件集合
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
//遍历SelectionKey,对事件进行处理
while(iterator.hasNext()){
SelectionKey key = iterator.next();
//如果是OP_ACCEPT连接事件。则进行连接获取和事件注册
if(key.isAcceptable()){
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel socketChannel = server.accept();
socketChannel.configureBlocking(false);
//注册读事件
socketChannel.register(selector, SelectionKey.OP_READ);
}else if(key.isReadable()){
//如果是OP_READ读事件。则进行读取
SocketChannel server = (SocketChannel) key.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(32);
int read = server.read(byteBuffer);
if(read > 0){
System.out.println("接收到消息:" + new String( byteBuffer.array() ));
} else if(read == -1){//如果客户端断开连接,关闭socket
iterator.remove();
server.close();
}
//从事件集合中删除本次处理的key,防止下次重复处理
iterator.remove();
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)