IO多路复用,select、poll和epoll简介

2024-08-26 02:20

本文主要是介绍IO多路复用,select、poll和epoll简介,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 前言
    • 1、select
    • 2、poll
    • 3、epoll
    • 4、总结

前言

select、poll 和 epoll 是 Linux 下用于多路复用 I/O(Input/Output)的系统调用,它们用于监视多个文件描述符,以查看哪个文件描述符上有可读、可写或发生了异常的事件。

1、select

select 是最早的多路复用 I/O 机制之一。它允许你监控多个文件描述符,以检测哪些文件描述符有事件发生。它通过修改一个位掩码来表示每个文件描述符的状态。

  • 使用方法
#include <sys/select.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>int main() {fd_set read_fds;int max_fd;struct timeval timeout;// 设置文件描述符集合FD_ZERO(&read_fds);FD_SET(STDIN_FILENO, &read_fds);max_fd = STDIN_FILENO;// 设置超时时间timeout.tv_sec = 5;timeout.tv_usec = 0;int ret = select(max_fd + 1, &read_fds, NULL, NULL, &timeout);if (ret == -1) {perror("select");exit(EXIT_FAILURE);} else if (ret == 0) {printf("Timeout occurred!\n");} else {if (FD_ISSET(STDIN_FILENO, &read_fds)) {printf("Data is available on stdin.\n");}}return 0;
}
  • select的几个宏
/*
用于将文件描述符添加到文件描述符集合中
fd:要添加的文件描述符。
fdset:要修改的文件描述符集合。
*/
void FD_SET(int fd, fd_set *fdset);/*
用于从文件描述符集合中删除指定的文件描述符
fd:要删除的文件描述符。
fdset:要修改的文件描述符集合。
*/
void FD_CLR(int fd, fd_set *fdset);/*
用于检查文件描述符集合中是否包含指定的文件描述符
fd:要检查的文件描述符。
fdset:要检查的文件描述符集合。
*/
int FD_ISSET(int fd, fd_set *fdset);/*
用于清空文件描述符集合
fdset:要清空的文件描述符集合。
*/
void FD_ZERO(fd_set *fdset);
  • select函数的五个参数含义
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

nfds: 监控的最大文件描述符值加1。
readfds: 监控可读事件的文件描述符集合。
writefds: 监控可写事件的文件描述符集合。
exceptfds: 监控异常事件的文件描述符集合。
timeout: 超时时间,指定 select 需要等待的时间。如果为 NULL,则 select 会一直等待直到有事件发生。

  • 优缺点分析

(1)优点
简单: select 的接口简单易用,广泛支持。
兼容性: 几乎所有 UNIX-like 操作系统都支持 select。
(2)缺点
文件描述符限制: 默认情况下,select 的文件描述符数量限制为 1024(可以通过重新编译内核或修改宏 FD_SETSIZE 增加,但不建议)。
性能瓶颈: 每次调用 select 都需要将文件描述符集合从用户态复制到内核态,这在文件描述符数量很大时可能会带来性能问题。
线性扫描: select 需要线性扫描文件描述符集合,效率较低。

2、poll

poll 是 select 的改进版,功能和 select 类似,但解决了一些 select 的局限性。poll 使用一个结构体数组来表示文件描述符及其相关的事件,而不是使用位掩码。

  • 使用方法
#include <poll.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>int main() {struct pollfd fds;int timeout = 5000; // 超时时间:5秒fds.fd = STDIN_FILENO;fds.events = POLLIN;fds.revents = 0;int ret = poll(&fds, 1, timeout);if (ret == -1) {perror("poll");exit(EXIT_FAILURE);} else if (ret == 0) {printf("Timeout occurred!\n");} else {if (fds.revents & POLLIN) {printf("Data is available on stdin.\n");}}return 0;
}
  • poll函数的参数
int poll(struct pollfd *fds, nfds_t nfds, int timeout);

fds: pollfd 结构体数组,每个结构体表示一个文件描述符及其事件。
nfds: pollfd 结构体数组的大小。
timeout: 超时时间,单位是毫秒。如果设置为 -1,poll 将无限期等待直到有事件发生;如果设置为 0,poll 将立即返回。

  • pollfd结构体
struct pollfd {int fd;         // 文件描述符short events;   // 监控的事件类型short revents;  // 实际发生的事件
};
  • 事件常量

POLLIN: 文件描述符可读(例如,有数据可读或连接可接受)。
POLLOUT: 文件描述符可写(例如,缓冲区有足够空间)。
POLLERR: 文件描述符发生错误。
POLLHUP: 文件描述符挂起(通常用于检测连接的关闭)。
POLLNVAL: 文件描述符无效(例如,关闭了的文件描述符)。

  • 优缺点分析

(1)优点
文件描述符数量无上限: 没有像 select 那样的文件描述符数量限制。
灵活性: 可以同时监控多个文件描述符及其事件。
(2)缺点
性能瓶颈: 每次调用 poll 时都需要遍历 pollfd 数组,这在监控大量文件描述符时会带来性能开销。

3、epoll

4、总结

select 适合处理少量文件描述符和需要跨平台支持的场景。它简单易用,但有文件描述符数量限制,并且在文件描述符数量多时性能较差。
poll 适合需要监控大量文件描述符的场景。它没有文件描述符数量限制,但在大量文件描述符时性能依然较差。

这篇关于IO多路复用,select、poll和epoll简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1107277

相关文章

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

业务协同平台--简介

一、使用场景         1.多个系统统一在业务协同平台定义协同策略,由业务协同平台代替人工完成一系列的单据录入         2.同时业务协同平台将执行任务推送给pda、pad等执行终端,通知各人员、设备进行作业执行         3.作业过程中,可设置完成时间预警、作业节点通知,时刻了解作业进程         4.做完再给你做过程分析,给出优化建议         就问你这一套下

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

easyui 验证下拉菜单select

validatebox.js中添加以下方法: selectRequired: {validator: function (value) {if (value == "" || value.indexOf('请选择') >= 0 || value.indexOf('全部') >= 0) {return false;}else {return true;}},message: '该下拉框为必选项'}

【Tools】AutoML简介

摇来摇去摇碎点点的金黄 伸手牵来一片梦的霞光 南方的小巷推开多情的门窗 年轻和我们歌唱 摇来摇去摇着温柔的阳光 轻轻托起一件梦的衣裳 古老的都市每天都改变模样                      🎵 方芳《摇太阳》 AutoML(自动机器学习)是一种使用机器学习技术来自动化机器学习任务的方法。在大模型中的AutoML是指在大型数据集上使用自动化机器学习技术进行模型训练和优化。

Java IO 操作——个人理解

之前一直Java的IO操作一知半解。今天看到一个便文章觉得很有道理( 原文章),记录一下。 首先,理解Java的IO操作到底操作的什么内容,过程又是怎么样子。          数据来源的操作: 来源有文件,网络数据。使用File类和Sockets等。这里操作的是数据本身,1,0结构。    File file = new File("path");   字

springboot体会BIO(阻塞式IO)

使用springboot体会阻塞式IO 大致的思路为: 创建一个socket服务端,监听socket通道,并打印出socket通道中的内容。 创建两个socket客户端,向socket服务端写入消息。 1.创建服务端 public class RedisServer {public static void main(String[] args) throws IOException {

多路转接之select(fd_set介绍,参数详细介绍),实现非阻塞式网络通信

目录 多路转接之select 引入 介绍 fd_set 函数原型 nfds readfds / writefds / exceptfds readfds  总结  fd_set操作接口  timeout timevalue 结构体 传入值 返回值 代码 注意点 -- 调用函数 select的参数填充  获取新连接 注意点 -- 通信时的调用函数 添加新fd到

Java基础回顾系列-第七天-高级编程之IO

Java基础回顾系列-第七天-高级编程之IO 文件操作字节流与字符流OutputStream字节输出流FileOutputStream InputStream字节输入流FileInputStream Writer字符输出流FileWriter Reader字符输入流字节流与字符流的区别转换流InputStreamReaderOutputStreamWriter 文件复制 字符编码内存操作流(

C++ I/O多路复用 select / poll / epoll

I/O多路复用:在网络I/O中,用 1个或1组线程 管理 多个连接描述符。             如果有至少一个描述符准备就绪,就处理对应的事件             如果没有,就会被阻塞,让出CPU给其他应用程序运行,直到有准备就绪的描述符 或 超时