I/O 多路复用:`select`、`poll`、`epoll` 和 `kqueue` 的区别与示例
I/O 多路复用是指在一个线程内同时监控多个文件描述符(File Descriptor, FD),以便高效地处理多个 I/O 事件。在 UNIX/Linux 和 BSD 系统中,select、poll、epoll、kqueue 都是实现 I/O 多路复用的系统调用。它们各有特点,适合不同的应用场景。本文将详细介绍它们的用法、优缺点,并附上相应的代码示例。

1. select
概述
select 是最早的 I/O 多路复用系统调用之一,广泛支持于各类操作系统中。它允许程序同时监视多个文件描述符,但有最大数量的限制(通常是 1024 个文件描述符)。
优点
- 简单,适用性广泛。
- 支持几乎所有 UNIX 类操作系统。
缺点
- 文件描述符数量有限制。
- 每次调用都需要重新设置文件描述符集合,效率较低。
使用示例
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <unistd.h>int main() {fd_set readfds;struct timeval timeout;int ret;// 初始化文件描述符集合FD_ZERO(&readfds);FD_SET(STDIN_FILENO, &readfds);// 设置超时时间timeout.tv_sec = 5;timeout.tv_usec = 0;printf("Waiting for input, timeout in 5 seconds...\n");// 调用 select 函数,监控文件描述符ret = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &timeout);if (ret == -1) {perror("select");exit(EXIT_FAILURE);} else if (ret == 0) {printf("Timeout occurred! No data after 5 seconds.\n");} else {if (FD_ISSET(STDIN_FILENO, &readfds)) {char buffer[1024];read(STDIN_FILENO, buffer, sizeof(buffer));printf("Data read: %s\n", buffer);}}return 0;
}
解释
在上述代码中,我们使用 select 函数监听标准输入 (STDIN_FILENO) 的可读性。如果用户在 5 秒内没有输入,程序会超时并退出。
2. poll
概述
poll 作为 select 的改进版本,消除了文件描述符数量的限制。它通过一个 pollfd 数组来管理多个文件描述符,解决了 select 的一些局限性。
优点
- 没有文件描述符数量限制。
- API 比较简洁,避免了
select需要重置文件描述符集合的问题。
缺点
- 和
select一样,每次调用仍需遍历整个文件描述符集合。
使用示例
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <unistd.h>int main() {struct pollfd fds[1];int ret;// 设置文件描述符和事件fds[0].fd = STDIN_FILENO;fds[0].events = POLLIN;printf("Waiting for input, timeout in 5 seconds...\n");// 调用 poll 函数,设置 5 秒超时ret = poll(fds, 1, 5000);if (ret == -1) {perror("poll");exit(EXIT_FAILURE);} else if (ret == 0) {printf("Timeout occurred! No data after 5 seconds.\n");} else {if (fds[0].revents & POLLIN) {char buffer[1024];read(STDIN_FILENO, buffer, sizeof(buffer));printf("Data read: %s\n", buffer);}}return 0;
}
解释
这里的代码使用 poll 来监控标准输入的可读性。与 select 类似,它设置了一个 5 秒的超时时间,但使用 poll 可以处理更多的文件描述符。
3. epoll
概述
epoll 是 Linux 特有的系统调用,它专门为处理大量文件描述符而设计,性能远优于 select 和 poll。epoll 使用一个事件通知机制,避免了每次调用时遍历整个文件描述符集合。
优点
- 高效,适合处理大量文件描述符。
- 不需要每次遍历整个文件描述符集合。
缺点
- 仅支持 Linux 系统。
使用示例
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <unistd.h>int main() {int epfd = epoll_create1(0);struct epoll_event event, events[1];int ret;if (epfd == -1) {perror("epoll_create1");exit(EXIT_FAILURE);}// 设置事件event.events = EPOLLIN;event.data.fd = STDIN_FILENO;if (epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &event) == -1) {perror("epoll_ctl");exit(EXIT_FAILURE);}printf("Waiting for input, timeout in 5 seconds...\n");// 调用 epoll_wait,等待事件ret = epoll_wait(epfd, events, 1, 5000);if (ret == -1) {perror("epoll_wait");exit(EXIT_FAILURE);} else if (ret == 0) {printf("Timeout occurred! No data after 5 seconds.\n");} else {if (events[0].data.fd == STDIN_FILENO) {char buffer[1024];read(STDIN_FILENO, buffer, sizeof(buffer));printf("Data read: %s\n", buffer);}}close(epfd);return 0;
}
解释
在这个示例中,我们使用 epoll 来监控标准输入。epoll_create1 创建了一个 epoll 实例,随后通过 epoll_ctl 添加文件描述符。epoll_wait 用来等待事件发生,效率远高于 select 和 poll。
4. kqueue
概述
kqueue 是 BSD 系统(包括 macOS)中的高效 I/O 事件通知机制。与 epoll 类似,kqueue 使用事件通知的机制来避免每次遍历整个文件描述符集合。
优点
- 高效,适合处理大量 I/O 事件。
- 支持 BSD 系统。
缺点
- 仅支持 BSD 系统(包括 macOS)。
使用示例
#include <stdio.h>
#include <stdlib.h>
#include <sys/event.h>
#include <sys/time.h>
#include <unistd.h>int main() {int kq = kqueue();struct kevent change, event;int ret;if (kq == -1) {perror("kqueue");exit(EXIT_FAILURE);}// 设置事件EV_SET(&change, STDIN_FILENO, EVFILT_READ, EV_ADD, 0, 0, NULL);printf("Waiting for input, timeout in 5 seconds...\n");// 调用 kevent,设置 5 秒超时struct timespec timeout = {5, 0};ret = kevent(kq, &change, 1, &event, 1, &timeout);if (ret == -1) {perror("kevent");exit(EXIT_FAILURE);} else if (ret == 0) {printf("Timeout occurred! No data after 5 seconds.\n");} else {if (event.ident == STDIN_FILENO) {char buffer[1024];read(STDIN_FILENO, buffer, sizeof(buffer));printf("Data read: %s\n", buffer);}}close(kq);return 0;
}
解释
在 BSD 系统中,kqueue 提供了一种高效的 I/O 事件通知机制。该代码监控标准输入,超时时间为 5 秒,使用 kevent 等待事件发生。
5. 总结
| 特性 | select | poll | epoll | kqueue |
|---|---|---|---|---|
| 支持的平台 | Unix/Linux/BSD | Unix/Linux/BSD | Linux | BSD/macOS |
| 文件描述符限制 | 有限制(1024) | 无限制 | 无限制 | 无限制 |
| 效率 | 较低 | 较低 | 高 | 高 |
| 扩展性 |
相关文章:
I/O 多路复用:`select`、`poll`、`epoll` 和 `kqueue` 的区别与示例
I/O 多路复用是指在一个线程内同时监控多个文件描述符(File Descriptor, FD),以便高效地处理多个 I/O 事件。在 UNIX/Linux 和 BSD 系统中,select、poll、epoll、kqueue 都是实现 I/O 多路复用的系统调用。它们各有特点࿰…...
大数据之Flink(三)
9.3、转换算子 9.3.1、基本转换算子 9.3.1.1、映射map 一一映射 package transform;import bean.WaterSensor; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator; impor…...
【HCIA-Datacom】IPv4地址介绍
| | 👉个人主页:Reuuse 希望各位多多支持!❀ | 👉HCIA专栏博客 | 最后如果对你们有帮助的话希望有一个大大的赞! | ⭐你们的支持是我最大的动力!⭐ | 目录 IPv4地址定义IPv4地址分类方式二级目录三级目录 I…...
maven父子工程多模块如何管理统一的版本号?
1.为什么要统一管理? maven父子工程多模块,每个模块还都可以独立存在,子模块往往通常希望和父工程保持一样的版本,如果每个工程单独定义版本号,后期变更打包也非常麻烦,如何维护一个全局的版本号呢&#x…...
JavaScript --函数的作用域(全局和局部)
全局作用域 全局作用域,就算不在一个script标签也能调用 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta nam…...
贪吃蛇项目实现(C语言)——附源码
前言 贪吃蛇是一款十分经典的游戏,其通过控制贪吃蛇的上下左右移动来吃食物,延长自己的身体,也会因为撞到墙体和自身而死亡。下面我们通过C语言来实现贪吃蛇。 1.技术要点 C语言枚举,结构体,链表,动态内…...
【C++】42道面试经典问题总结
C this指针是干什么用的? 假如一个类型定义了很多对象,类里面有很多定义的私有成员变量,共享一套成员方法。通过this指针这可以区分方法、变量是操作的哪个对象的。 C的new和delete,new[]和delete[]可以混用吗? 一般来…...
php 实现JWT
在 PHP 中,JSON Web Token (JWT) 是一种开放标准 (RFC 7519) 用于在各方之间作为 JSON 对象安全地传输信息。JWT 通常用于身份验证系统,如 OAuth2 或基于令牌的身份验证。 以下是一个基本的 PHP 实现 JWT 生成和验证的代码示例。 JWT 的组成部分 JWT …...
vue table id一样的列合并
合并场景:如果id一样,则主表列合并,子表列不做合并,可实现单行、多行合并,亲测!!! 展示效果如图示: 组件代码: // table组件 :span-method"objectSpa…...
xshell密钥方式连接阿里云Linux
前提条件 有阿里云ECS linux实例安装好xshell工具 步骤 创建密钥对并绑定ECS实例 浏览器登录阿里云-->控制台-->ECS服务器-->网络与安全-->密钥对-->创建密钥对 根据提示填写密钥名称-->选中默认资源组-->创建 创建完成,会自动下载密钥对的…...
Wni11 下 WSL 安装 CentOS
Wni11 下 WSL 安装 CentOS 方法一、安装包安装下载包安装安装打开 CentOS1. 从 Windows 终端 打开2. 从 PowerShell 打开 方法二、导入 CentOS 的 tar 文件进行安装0. 查看版本(可选)1. 导出 Docker 容器到 tar 文件2. 将 tar 文件导入 WSL2.1. 导入 tar…...
ROADM(可重构光分插复用器)-介绍
1. 引用 https://zhuanlan.zhihu.com/p/163369296 https://zhuanlan.zhihu.com/p/521352954 https://zhuanlan.zhihu.com/p/91103069 https://zhuanlan.zhihu.com/p/50610236 术语: 英文缩写描述灰光模块彩光模块CWDM:Coarse Wave-Length Division …...
HarmonyOS开发之路由跳转
文章目录 一、路由跳转模式与实例1.router.pushUrl2.router.replaceUrl3.router.back 一、路由跳转模式与实例 跳转模式 有点类似于vue的路由跳转 router.pushUrl 保留路由栈,保留当前的页面;router.replaceUrl 销毁当前页面,跳转一个新的页…...
怎么使用ai 免费生成ppt?这4个工具可以帮忙
随之AI工具的流行,网络上也涌现了一批 AIPPT 工具,可以在办公上帮助我们节省很多制作PPT的时间。通常它们的操作也比较简单,所以适合很多人使用。为了可以帮助大家提高办公效率,我在这里跟大家分享4款可以免费使用的AIPPT制作工具…...
Android主副屏显示-Android13
Android主副屏显示-Android13 1、DisplayDeviceInfo屏幕信息2、每个屏幕对应LogicalDisplay2.1 LogicalDisplay添加对应DisplayContent2.2 configureDisplayLocked刷新 DisplayManagerService启动及主屏添加-Android13 1、DisplayDeviceInfo屏幕信息 DisplayManagerService启动…...
什么是 SMB 服务器以及它如何工作?
在本文中,您将了解 SMB 服务器以及它们如何促进网络文件共享。 我们将介绍它们的基本功能、主要特性以及如何安全地设置它们。无论您是新手还是需要复习,本指南都将帮助您更好地了解 SMB 服务器。 什么是 SMB 服务器? SMB(服务器…...
【python计算机视觉编程——10.OpenCV】
python计算机视觉编程——10.OpenCV 10.OpenCV10.2 OpenCV基础知识10.2.1 读取和写入图像10.2.2 颜色空间10.2.3 显示图像及结果 10.3 处理视频10.3.1 视频输入10.3.2 将视频读取到NumPy数组中 10.4 跟踪10.4.1 光流10.4.2 Lucas-Kanade算法使用跟踪器使用发生器 10.5 更多示例…...
医学数据分析实训 项目二 数据预处理预备知识(数据标准化处理,数据离差标准化处理,数据二值化处理,独热编码处理,数据PCA降维处理)
文章目录 数据预处理预备知识任务一 数据标准化处理1. 数据准备2. 数据标准化 任务二 数据离差标准化处理任务三 数据二值化处理任务五 独热编码处理对数据进行“离散化处理”(装箱)将已经装箱的数据进行OneHotEncoder独热编码 任务六 数据PCA降维处理1.…...
MySQL查询执行(四):查一行也很慢
假设存在表t,这个表有两个字段id和c,并且我在里面插入了10万行记录。 -- 创建表t CREATE TABLE t (id int(11) NOT NULL,c int(11) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB;-- 通过存储过程向t写入10w行数据 delimiter ;; create procedure idat…...
【Obsidian】当笔记接入AI,Copilot插件推荐
当笔记接入AI,Copilot插件推荐 自己的知识库笔记如果增加AI功能会怎样?AI的回答完全基于你自己的知识库余料,是不是很有趣。在插件库中有Copilot插件这款插件,可以实现这个梦想。 一、什么是Copilot? 我们知道githu…...
终极macOS清理神器:Pearcleaner 3步彻底卸载应用不留痕迹
终极macOS清理神器:Pearcleaner 3步彻底卸载应用不留痕迹 【免费下载链接】Pearcleaner A free, source-available and fair-code licensed mac app cleaner 项目地址: https://gitcode.com/gh_mirrors/pe/Pearcleaner 你是否曾将macOS应用拖入废纸篓后&…...
3DS游戏格式转换神器:5分钟让.3ds文件变身为可安装的CIA
3DS游戏格式转换神器:5分钟让.3ds文件变身为可安装的CIA 【免费下载链接】3dsconv Python script to convert Nintendo 3DS CCI (".cci", ".3ds") files to the CIA format 项目地址: https://gitcode.com/gh_mirrors/3d/3dsconv 还在为…...
Thorium浏览器深度解析:5个核心优势与进阶配置实战
Thorium浏览器深度解析:5个核心优势与进阶配置实战 【免费下载链接】thorium Chromium fork named after radioactive element No. 90. Source code and Linux releases. Windows/MacOS/ARM builds served in different repos, links are towards the top of the RE…...
Forge模组开发效率提升:Gradle插件自动化构建与热部署实践
1. 项目概述:一个为Forge模组开发者准备的“瑞士军刀”如果你是一名Minecraft Forge模组的开发者,或者你正打算踏入这个充满创造力的领域,那么你大概率经历过这样的场景:为了测试一个简单的功能改动,你需要反复地执行g…...
Python与ChatGPT构建智能办公自动化:从任务分解到智能体系统
1. 项目概述:用Python与ChatGPT联手,让办公自动化“开口说话”如果你每天还在重复着打开Excel、复制粘贴数据、手动写邮件、整理报告这些枯燥的活儿,那这个项目可能就是你的“数字员工”入职通知书。Sven-Bo/automate-office-tasks-using-cha…...
All in Token,移动,电信,联通,百度,阿里,字节,华为,Token战争,Token无用:李彦宏用DAA终结了AI的度量衡之争
今年4月,AI行业出现了一组让投资人坐立难安的数据:Anthropic年化营收突破300亿美元,正式超过OpenAI的约250亿美元。但反常的是,据第三方机构估算,Claude的月活用户仅约为ChatGPT的2.44%。以及,Anthropic的模…...
CircuitPython嵌入式游戏开发:基于TileGrid的迷宫寻蛋与JSON数据持久化实践
1. 项目概述与核心价值如果你和我一样,对嵌入式开发充满热情,同时又对游戏开发抱有好奇心,那么将两者结合——在微控制器上编写一个完整的2D游戏——绝对是一次令人兴奋的挑战。这不仅仅是让LED闪烁或读取传感器数据,而是要在资源…...
OpenClaw实战教程:声明式配置驱动的高效数据抓取方案
1. 项目概述:一个关于“OpenClaw”的实战教程 最近在GitHub上看到一个挺有意思的项目,叫“OpenClawTuto”。光看名字,你可能会有点摸不着头脑,这“OpenClaw”到底是个啥?是某种开源机械爪?还是一个代号&…...
【仅剩217份】《Midjourney后印象派风格白皮书》V2.3——含17位艺术家专属LoRA适配建议、32组跨文化色彩映射表及实时风格强度校准工具(2024.06内部封测版)
更多请点击: https://intelliparadigm.com 第一章:后印象派风格的视觉基因与Midjourney语义解码 后印象派并非对自然的模仿,而是对色彩、结构与主观情绪的系统性重构——梵高旋转的星云、塞尚凝固的苹果、高更平面化的塔希提图腾,…...
C# AI开发实战:BotSharp框架构建企业级NLP应用指南
1. 项目概述:当C#开发者遇上AI应用开发如果你是一名长期深耕.NET生态的开发者,最近看着Python在AI领域风生水起,心里是不是有点痒,又有点不甘?总觉得为了跑个模型、搭个智能对话,就得切到另一个完全不同的技…...
