IO多路复用,epoll和select的区别

简介: IO多路复用,epoll和select的区别

IO多路复用

什么是IO多路复用,假设有1000个文件或者网络IO需要我们处理,这里统称为IO,无论IO是否阻塞,总需要有线程去等待IO的完成,那么难道有1000个IO,就要去开1000个线程去监听吗,这样做资源浪费太过严重,所以不同的系统提供了不同的IO多路复用(select,poll,epoll)

I/O 多路复用被用来处理同一个事件循环中的多个 I/O 事件。I/O 多路复用需要使用特定的系统调用,最常见的系统调用是 epoll

epoll

将检测文件描述符的变化委托给内核去处理, 然后内核将发生变化的文件描述符对应的事件返回给应用程序

epoll的底层是红黑树

函数介绍:

int epoll_create(int size)

函数说明: 创建一个树根

参数说明:

  • size: 最大节点数, 此参数在linux 2.6.8已被忽略, 但必须传递一个大于0的数

返回值:

  • 成功: 返回一个大于0的文件描述符, 代表整个树的树根
  • 失败: 返回-1, 并设置errno值

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)

函数说明: 将要监听的节点在epoll树上添加, 删除和修改

参数说明:

  • epfd: epoll树根
  • op:

EPOLL_CTL_ADD: 添加事件节点到树上

EPOLL_CTL_DEL: 从树上删除事件节点

EPOLL_CTL_MOD: 修改树上对应的事件节点

  • fd: 事件节点对应的文件描述符
  • event: 要操作的事件节点
struct epoll_event {
  uint32_t     events;      /* Epoll events */
  epoll_data_t data;        /* User data variable */
};
typedef union epoll_data {
  void        *ptr;
  int          fd;
  uint32_t     u32;
  uint64_t     u64;
} epoll_data_t;

event.events常用的有:

  • EPOLLIN: 读事件
  • EPOLLOUT: 写事件
  • EPOLLERR: 错误事件
  • EPOLLET: 边缘触发模式

event.fd: 要监控的事件对应的文件描述符

epoll的两种模式ET和LT模式

  • 水平触发: 只要缓冲区中有数据, 就一直通知
  • 边缘触发: 缓冲区中有数据只会通知一次, 之后再有数据才会通知(若是读数据的时候没有读完, 则剩余的数据不会再通知, 直到有新的数据到来),边缘非阻塞模式: 提高效率

select

多路IO技术: select, 同时监听多个文件描述符, 将监控的操作交给内核去处理,

数据类型

int select(int nfds, fd_set * readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)

函数介绍: 委托内核监控该文件描述符对应的读,写或者错误事件的发生

参数说明:

  • fd_set: 文件描述符集合
  • nfds: 最大的文件描述符+1
  • readfds: 读集合, 是一个传入传出参数
    传入: 指的是告诉内核哪些文件描述符需要监控

传出: 指的是内核告诉应用程序哪些文件描述符发生了变化

  • writefds: 写文件描述符集合(传入传出参数)
  • execptfds: 异常文件描述符集合(传入传出参数)
  • timeout:
    NULL–表示永久阻塞, 直到有事件发生
    0 --表示不阻塞, 立刻返回, 不管是否有监控的事件发生
    >0–到指定事件或者有事件发生了就返回

返回值:

  • 成功返回发生变化的文件描述符的个数
  • 失败返回-1, 并设置error值

select优点:

  1. 一个进程可以支持多个客户端
  2. select支持跨平台

select缺点:

  1. 代码编写困难
  2. 会涉及到用户区到内核区的来回拷贝
  3. 当客户端多个连接, 但少数活跃的情况, select效率较低
    例如: 作为极端的一种情况, 3-1023文件描述符全部打开, 但是只有1023有发送数据, select就显得效率低下
  4. 最大支持1024个客户端连接,select最大支持1024个客户端连接不是有文件描述符表最多可以支持1024个文件描述符限制的, 而是由FD_SETSIZE=1024限制的。FD_SETSIZE=1024 fd_set使用了该宏, 当然可以修改内核, 然后再重新编译内核, 一般不建议这么做。

epoll,poll,select总结

select:能够监听的文件描述符最多1024个,实际生产中往往不够用,并且有事件触发了要轮询所有的IO事件,效率低下

poll:本质上和select没什么区别,只是突破了1024这个限制

epoll:没有最大并发连接的限制,而且效率提升,不是轮询的方式,只有有事件发生的event才会返回


目录
相关文章
|
15天前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
9天前
|
消息中间件 NoSQL Java
面试官:谈谈你对IO多路复用的理解?
面试官:谈谈你对IO多路复用的理解?
23 0
面试官:谈谈你对IO多路复用的理解?
|
11天前
|
网络协议 Java Linux
高并发编程必备知识IO多路复用技术select,poll讲解
高并发编程必备知识IO多路复用技术select,poll讲解
|
3月前
|
安全 Java Linux
(七)Java网络编程-IO模型篇之从BIO、NIO、AIO到内核select、epoll剖析!
IO(Input/Output)方面的基本知识,相信大家都不陌生,毕竟这也是在学习编程基础时就已经接触过的内容,但最初的IO教学大多数是停留在最基本的BIO,而并未对于NIO、AIO、多路复用等的高级内容进行详细讲述,但这些却是大部分高性能技术的底层核心,因此本文则准备围绕着IO知识进行展开。
136 1
|
3月前
|
存储 Linux 网络安全
Centos安装Docker的详细安装步骤,Docker相关组件:docker-ce-cli、docker-ce和containerd.io的区别
Centos安装Docker的详细安装步骤,Docker相关组件:docker-ce-cli、docker-ce和containerd.io的区别;CentOS7安装DockerCompose;Docker镜像仓库
616 11
|
3月前
|
存储 Java Unix
(八)Java网络编程之IO模型篇-内核Select、Poll、Epoll多路复用函数源码深度历险!
select/poll、epoll这些词汇相信诸位都不陌生,因为在Redis/Nginx/Netty等一些高性能技术栈的底层原理中,大家应该都见过它们的身影,接下来重点讲解这块内容。
|
2月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
3月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
2月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
28 2
|
2月前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。