Java BIO NIO解析

Java BIO NIO解析

BIO 阻塞IO。

一次只处理一个请求。如果连接了但是没有发送数据,也一直会阻塞,等待连接数据。直到连接断开,才能处理下一个请求。(单线程)

优化 :

  1. 使用多线程来处理连接。一个连接用一个线程去处理。但是如果一直创建线程消耗资源也很大。
  2. 池化思想 -> 线程池。但是这样请求数大于线程池最大的数量且一直不断开情况,后面的请求仍然处于阻塞状态。

NIO 非阻塞IO

单个线程处理多个请求,且不会阻塞请求。通过中断回调函数实现。

将连接注册进channel中,再将channel注册进selector中。当收到请求数据时,回调通知系统有(收到read/发送write/error)事件,系统再根据相应的事件进行处理。
底层使用linux的epoll机制。(早期版本使用select )

Linux epoll底层原理

前生 -> select/poll
select 一直轮询,但是只能处理有限个fd
poll 也是轮询,但是可以处理无限个fd

epoll是Linux内核为处理大批量文件描述符(fd -> file describe)而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。

先用 epoll_create函数创建一个 epoll实例,再用epoll_ctl函数监听前面创建的epoll对象发生的事件(函数调用时传入事件类型)。最后调用epoll_wait函数等待事件发生,如果有则回调,没有就阻塞等待。

底层使用中断程序来实现。当中断程序发生时,会要求cpu优先处理中断程序,处理完后再继续处理原来停止的任务。 由此效率才有明显的提升。
中断程序词条

  1. int epoll_create(int size)
    该函数生成一个epoll专用的文件描述符。它其实是在内核申请一空间,用来存放你想关注的socket fd上是否发生以及发生了什么事件。size就是你在这个epoll fd上能关注的最大socket fd数。随你定好了。只要你有空间。
  2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
    该函数用于控制某个epoll文件描述符上的事件,可以注册事件,修改事件,删除事件。
    参数:
    epfd:由 epoll_create 生成的epoll专用的文件描述符;
    op:要进行的操作例如注册事件,可能的取值EPOLL_CTL_ADD 注册、EPOLL_CTL_MOD 修 改、EPOLL_CTL_DEL 删除
    fd:关联的文件描述符;
    event:指向epoll_event的指针;
    如果调用成功返回0,不成功返回-1
  3. int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout)
    参数:
    epfd:由epoll_create 生成的epoll专用的文件描述符;
    epoll_event:用于回传代处理事件的数组;
    maxevents:每次能处理的事件数;
    timeout:等待I/O事件发生的超时值(单位我也不太清楚);-1相当于阻塞,0相当于非阻塞。一般用-1即可
    返回发生事件数。
    epoll_wait运行的原理是
    等侍注册在epfd上的socket fd的事件的发生,如果发生则将发生的sokct fd和事件类型放入到events数组中。
    并 且将注册在epfd上的socket fd的事件类型给清空,所以如果下一个循环你还要关注这个socket fd的话,则需要用epoll_ctl(epfd,EPOLL_CTL_MOD,listenfd,&ev)来重新设置socket fd的事件类型。这时不用EPOLL_CTL_ADD,因为socket fd并未清空,只是事件类型清空。这一步非常重要。

Redis多路复原解析

在不同的os下使用不同的机制。Linux使用epoll。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值