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才会返回


目录
相关文章
|
2月前
|
网络协议 安全 Linux
Linux C/C++之IO多路复用(select)
这篇文章主要介绍了TCP的三次握手和四次挥手过程,TCP与UDP的区别,以及如何使用select函数实现IO多路复用,包括服务器监听多个客户端连接和简单聊天室场景的应用示例。
97 0
|
2月前
|
存储 Linux C语言
Linux C/C++之IO多路复用(aio)
这篇文章介绍了Linux中IO多路复用技术epoll和异步IO技术aio的区别、执行过程、编程模型以及具体的编程实现方式。
102 1
Linux C/C++之IO多路复用(aio)
|
2月前
|
Linux C++
Linux C/C++之IO多路复用(poll,epoll)
这篇文章详细介绍了Linux下C/C++编程中IO多路复用的两种机制:poll和epoll,包括它们的比较、编程模型、函数原型以及如何使用这些机制实现服务器端和客户端之间的多个连接。
34 0
Linux C/C++之IO多路复用(poll,epoll)
|
2月前
|
Java Linux
【网络】高并发场景处理:线程池和IO多路复用
【网络】高并发场景处理:线程池和IO多路复用
55 2
|
2月前
|
监控 网络协议 Java
IO 多路复用? 什么是 IO 多路复用? 简单示例(日常生活)来解释 IO 多路复用 一看就懂! 大白话,可爱式(傻瓜式)教学! 保你懂!
本文通过日常生活中的简单示例解释了IO多路复用的概念,即一个线程通过监控多个socket来处理多个客户端请求,提高了效率,同时介绍了Linux系统中的select、poll和epoll三种IO多路复用的API。
150 2
|
2月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
96 1
|
3月前
|
消息中间件 NoSQL Java
面试官:谈谈你对IO多路复用的理解?
面试官:谈谈你对IO多路复用的理解?
53 0
面试官:谈谈你对IO多路复用的理解?
|
3月前
|
网络协议 Java Linux
高并发编程必备知识IO多路复用技术select,poll讲解
高并发编程必备知识IO多路复用技术select,poll讲解
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
5月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用