Linux网络模型浅析

本文解释了网络模型中的同步阻塞IO、同步非阻塞IO(NIO)、多路复用(如epoll)、信号驱动和异步IO(AIO)的区别,指出Javanio包中的模型与Linux层面的区别,强调了在不同场景下选择合适的IO模型以提高效率和资源管理。
摘要由CSDN通过智能技术生成

要想理解这几个基本的网络模型需要认清楚以下几点:

1、不要被 “阻塞”、“非阻塞” 的字面意思所误导;

2、需要清楚 ”内核态“、”用户态“ 的基本概览;

3、Java nio 包中的网络模型,并不是Linux层面所讲的”同步非阻塞IO模型(NIO)“;

4、传统的BIO并不是说一定不可用,某些场景下反而更适合;

如下6种

1、同步阻塞IO(BIO):

  • 应用程序【用户态】需要为每个连接提供一个线程来处理网络io事件;
  • 这里的”阻塞“更大意义上是偏向【可能导致大量的线程资源处于阻塞的状态】;
  • 线程资源宝贵,无法大量创建;
  • 线程过多切换,效率损耗;
  • 这些线程会在io过程中进行等待,干不了其他事情;
  • 编码简单,【并发低&连接少】场景下的首选(几个-几十个);
  • 应用程序端可以使用线程池;

2、同步非阻塞IO(NIO):

  • 并不是等同于Java中的nio包下的编程模型;
  • 该种模型实际运用非常少见;
  • 个人理解,它甚至不如BIO;
  • 如果不加以优化改造,还是需要大量的线程,每个连接需要分配一个;
  • 只不过这些线程不是阻塞等待io结果响应,而生一直忙轮询;

3、多路复用:

  • 目前互联网上使用最多的io模型;
  • Java nio 包其实是对这种模型的实现;
  • select/poll/epoll 分别对应着三种多路复用管理的手段,随着linux内核版本的升级而逐步升级;
  • 重点在epoll的特性及优势上面;
  • 应用程序只需要使用一个线程就可以感知到多个连接的io事件,存在就绪的io事件以后,应用程序可选择主动处理(使用线程池);
  • 不再需要开辟大量的线程资源,阻塞等待;
  • 不再需要浪费大量的线程空轮询耗费cpu;

4、信号驱动:

信号驱动模式利用linux信号机制,通过sigaction函数将sigio读写信号以及handler回调函数注册到内核队列中,注册后应用进程不堵塞,可以去干别的工作。当网络IO状态发生变化时触发SIGIO中断,通过调用应用程序的handler通知应用程序网络IO就绪了。信号驱动的前半部分操作是异步行为,后面的网络数据操作仍然属于同步阻塞行为。

  • 内核io事件就绪会通知用户态;
  • 用户态再进行数据读取(内核态->用户态);

5、异步IO(AIO):

异步IO通过一些列异步API实现,是五种IO模式中唯一个真正的异步模式,目前Java的AIO使用的就是本模式。异步模式的读操作通过调用内核的aio_read函数来实现。应用线程调用aio_read,递交给内核一个用户空间下的缓冲区。内核收到请求后立刻返回,不阻塞应用线程。当网络设备的数据到来后,内核会自动把数据从内核空间拷贝到aio_read函数递交的用户态缓存。拷贝完成后以信号的方式通知用户线程,用户线程拿到数据后就可以执行后续操作。

  • 应用程序在【内核】io准备(用户态不可访问io结果)的阶段,不需要任何一个线程轮询或者阻塞等待;
  • 类似【内核】主动带着应用程序可访问的数据来回调应用程序;
     

参考文章:

好文推荐

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进窄门见微光行远路

如果对你有比较大的帮助

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值