Linux 下 poll 详解
在Linux系统编程中,poll
是一个强大的多路复用(I/O 多路复用)函数,用于同时监控多个文件描述符的事件,特别是在处理网络套接字或其他I/O设备时。相比于select
,poll
支持监控更多的文件描述符,并且没有像select
那样的文件描述符数量限制。
一、poll
函数介绍
poll
函数用于在指定的超时时间内监视一组文件描述符,并返回文件描述符上是否有指定的I/O事件发生。
函数原型
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
fds
:是一个数组,每个元素是一个pollfd
结构,描述一个文件描述符及其要监视的事件。nfds
:要监视的文件描述符个数。timeout
:等待的超时时间(以毫秒为单位)。-1表示无限等待,0表示立即返回(非阻塞模式)。
pollfd
结构体
struct pollfd { int fd; // 要监视的文件描述符
short events; // 等待的事件
short revents; // 实际发生的事件
};
fd
:要监视的文件描述符,例如套接字或管道。events
:感兴趣的事件,可以是以下的值的组合:POLLIN
:有数据可读。POLLOUT
:可以写数据(不会阻塞)。POLLERR
:发生错误。POLLHUP
:挂起事件(对方关闭连接)。POLLNVAL
:非法的文件描述符。
revents
:poll
返回时,实际发生的事件。
返回值
- 成功时,返回大于0的值,表示有多少文件描述符有事件发生。
- 如果超时且无事件发生,返回0。
- 失败时,返回-1,并设置
errno
。
二、poll
的使用步骤
- 创建并初始化
pollfd
数组:为需要监控的文件描述符设置监视事件。 - 调用
poll
函数:传入pollfd
数组、数组大小和超时时间。 - 处理事件:根据返回的
revents
判断哪个文件描述符有事件发生,并做出相应处理。
三、poll
示例
下面是一个使用 poll
监视两个套接字的简单例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <poll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define PORT 8080
#define MAX_EVENTS 2int main() {int listenfd, connfd;struct sockaddr_in serv_addr;struct pollfd fds[MAX_EVENTS];int nfds = 1;// 创建监听套接字if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {perror("socket failed");exit(EXIT_FAILURE);}serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = INADDR_ANY;serv_addr.sin_port = htons(PORT);// 绑定并监听端口if (bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {perror("bind failed");close(listenfd);exit(EXIT_FAILURE);}if (listen(listenfd, 3) < 0) {perror("listen failed");close(listenfd);exit(EXIT_FAILURE);}// 初始化pollfd数组fds[0].fd = listenfd;fds[0].events = POLLIN;printf("Waiting for connections...\n");while (1) {int ret = poll(fds, nfds, -1); // 无限等待事件if (ret < 0) {perror("poll failed");exit(EXIT_FAILURE);}// 检查监听套接字是否有新连接if (fds[0].revents & POLLIN) {struct sockaddr_in client_addr;socklen_t addr_len = sizeof(client_addr);if ((connfd = accept(listenfd, (struct sockaddr*)&client_addr, &addr_len)) < 0) {perror("accept failed");exit(EXIT_FAILURE);}printf("New connection accepted\n");}}close(listenfd);return 0;
}
这个例子中,程序首先创建了一个监听套接字,然后使用 poll
函数监视这个套接字的 POLLIN
事件(有新的连接到来)。当有新连接时,程序通过 accept
函数接收连接。
四、常用API介绍
在使用poll
和其他多路复用函数时,通常会涉及以下API:
-
socket
:创建一个套接字,用于网络通信。int socket(int domain, int type, int protocol);
-
bind
:将一个套接字绑定到一个特定的地址和端口。int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
-
listen
:将一个套接字设置为监听模式,等待客户端的连接。int listen(int sockfd, int backlog);
-
accept
:从监听套接字接受一个新的连接。int accept(int sockfd, struct sockaddr *addr,
socklen_t *addrlen);
-
connect
:客户端用于连接到服务端的套接字。int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
-
recv
和send
:分别用于接收和发送数据。ssize_t recv(int sockfd, void *buf, size_t len, int flags); ssize_t send(int sockfd, const void *buf, size_t len,
int flags);
-
close
:关闭文件描述符。int close(int fd);
五、poll
与select
的对比
- 灵活性:
poll
可以处理更多的文件描述符,不受select
的硬性限制。 - 事件通知:
poll
的pollfd
数组更加直观,每个文件描述符有自己的事件和返回事件。 - 效率:
poll
的实现较select
高效,特别是在需要监控大量文件描述符的场景中。
六、结语
poll
提供了一种高效且灵活的方式来监控多个文件描述符的事件,特别适用于网络编程和I/O密集型应用。在实际应用中,poll
被广泛应用于高并发服务器、事件驱动框架等场景中。
如果对文件描述符数量和性能要求更高,还可以考虑使用 epoll
,它是 Linux 下的增强版 poll
,在处理大规模并发连接时更加高效。
相关文章:

Linux 下 poll 详解
在Linux系统编程中,poll 是一个强大的多路复用(I/O 多路复用)函数,用于同时监控多个文件描述符的事件,特别是在处理网络套接字或其他I/O设备时。相比于select,poll 支持监控更多的文件描述符,并…...

virtualbox配置为NAT模式后物理机和虚拟机互通
virtualbox配置为 NAT模式后,虚拟机分配到的 IP地址一般是 10.xx网段的,虚拟机可以通过网络地址转换访问物理机所在的网络,但若不做任何配置,则物理机无法直接访问虚拟机。 virtualbox在提供 NAT配置模式时,也提供了端…...

工程机械车辆挖掘机自卸卡车轮式装载机检测数据集VOC+YOLO格式2644张3类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2644 标注数量(xml文件个数):2644 标注数量(txt文件个数):2644 标注…...

[Notepad++] 文本编辑器的下载及详细安装使用过程(附有下载文件)
程序员常用的文本编辑器Notepad,用于修改配置文件等 下载链接在文末 下载压缩包后解压 !!安装路径不要有中文 解压文件,得到 双击exe文件 选择简体中文,点击OK 点击下一步 点击“我接受” 更改安装目录,不…...

深入浅出Java多线程(六):Java内存模型
引言 大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第六篇内容:Java内存模型。大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!! 在并发编程中…...

注册了个小趴菜999#it#com
注册了个 999#it#com 拿着玩玩吧 现在二级域名竟然也让注册了 不过cn.com的二级似乎早就可以了...

UE4 材质学习笔记02(数据类型/扭曲着色器)
一.什么是数据类型 首先为啥理解数据类型是很重要的。一些节点的接口插槽只接受特定类型的数据,如果连接了不匹配的数据就会出现错误,有些接口可以接受任何数据类型,但是实际上只会使用到其中的一些。并且有时可以将多个数据流合并成一个来编…...

Linux驱动开发(速记版)--设备树插件
第六十八章 设备树插件介绍 Linux 4.4之后引入了动态设备树,其中的设备树插件(Device Tree Overlay)是一种扩展机制,允许在运行时动态添加、修改或删除设备节点和属性。 设备树插件机制通过DTS(设备树源文件࿰…...

代码报错后如何定位问题
文章目录 一、查看终端报错Exception二、百度三、问 一、查看终端报错Exception 代码报错时,终端一般都会有xxxException异常提示,或者exception、error…等字样提示,就顺着这些关键字提醒找到异常即可。 二、百度 不知道这个英文的异常是…...

Python数据可视化--Matplotlib--入门
我生性自由散漫,不喜欢拘束。我谁也不爱,谁也不恨。我没有欺骗这个,追求那个;没有把这个取笑,那个玩弄。我有自己的消遣。 -- 塞万提斯 《堂吉诃德》 Matplotlib介绍 1. Matplotlib 是 Python 中常用的 2D 绘图库&a…...

美国食品等级FDA认证测试介绍
美国FDA认证概览 美国食品和药物管理局(FDA)是负责监管食品、药品、医疗设备和化妆品等的联邦机构,以确保这些产品对公众健康和安全的影响。FDA认证在美国属于强制性认证,对产品的安全性和质量有着严格的要求。通过FDA认证&#…...

Vue2如何在网页实现文字的逐个显现
目录 Blue留言: 效果图: 实现思路: 代码: 1、空字符串与需渲染的字符串的定义 2、vue的插值表达式 3、函数 4、mounted()函数调用 结语: Blue留言: 在国庆前夕,突发奇想,我想…...

mybatisplus的查询,分页查询,自定义多表查询,修改的几种写法
使用mybatisplus的Db类简化写法 使用静态调用的方式,执行CRUD方法,避免Spring环境下Service循环注入、简洁代码,提升效率需要项目中已注入对应实体的BaseMapper完整使用方式见官方测试用例:官方测试用例地址对于参数为Wrapper的&…...

括号匹配判断
本题实现求表达式中括号是否匹配。只需判断表达式中括号(本题中只会出现三种括号,分别是小括号,中括号和大括号)是否匹配,表达式中可以有其他值也可没有。 函数接口定义: int match (char *exp); 其中 …...

数据结构(栈和队列的实现)
1. 栈(Stack) 1.1 栈的概念与结构 栈是一种特殊的线性表,其只允许固定的一段插入和删除操作;进行数据插入和删除的一段叫做栈顶,另一端叫栈底;栈中的元素符合后进先出LIFO(Last In First Out&…...

Python批量处理客户明细表格数据,挖掘更大价值
批量处理 .xls 数据并进行归类分析以挖掘内在价值,通常涉及以下步骤: 读取数据:使用 pandas 库读取 .xls 文件。数据清洗:处理缺失值、异常值、重复值等。数据转换:对数据进行必要的转换,如日期格式统一、…...

NAND Flash虚拟层索引表机制
NAND Flash虚拟层的索引表用于建立逻辑块与数据块、日志块之间的关系,用于NAND Flash虚拟层在运行过程中的读写、擦除操作;由于NAND Flash虚拟层采用集中索引的方式,因此在NAND Flash虚拟层启动时需要在NAND Flash存放索引表区域扫描并确定NAND Flash中存…...

Spring Boot框架:新闻推荐系统开发新趋势
3系统分析 3.1可行性分析 通过对本新闻推荐系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本新闻推荐系统采用JAVA作为开发语言,Spring Boot框…...

RK3568平台(opencv篇)opencv处理图像
一.颜色转换 cv2.cvtColor()函数功能: 将一幅图像从一个色彩空间转换到另一个色彩空间。 函数原型: cv2.cvtColor(src,code,dst=None,dstCn=None) 参数定义: src:要转换的源文件 code,转换的色彩空间,在 opencv 中有超过 150 种颜色空间转换方法,但是经常用的只有 B…...

【移动端】Viewport 视口
1. 什么是 Viewport(视口)? Viewport(视口)是指浏览器中用户可见的那部分网页内容的区域,简单来说,它是用户当前看到的网页的“窗口”区域。在不同的设备上,Viewport 的大小会有所不…...

PWM 模式
一、介绍 PWM(脉宽调制,Pulse-width modulation)是一种通过调节脉冲信号的宽度来控制电能输出的方法。PWM是一种方波信号,通常在电子和电气工程中用于调节功率输送,控制电机速度,调节LED亮度,以…...

模拟算法(3)_Z字形变换
个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 模拟算法(3)_Z字形变换 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. 题目链…...

Go语言实现长连接并发框架 - 任务执行流路由模块
文章目录 前言接口结构体接口实现项目地址最后 前言 你好,我是醉墨居士,上篇博客中我们实现了任务执行流上下文部分,接下来我们实现一下任务执行流的路由模块,基于该模块可以实现将消息转发到相应注册的任务执行流中进行处理 接…...

Windows 编译 FFmpeg 源码详细教程
FFmpeg FFmpeg 是一个开源的多媒体框架,它包括了一整套工具和库,可以用来处理(转码、转换、录制、流式传输等)音频和视频。FFmpeg 支持广泛的音视频格式,并且可以在多种操作系统上运行,包括 Windows、Linux 和 macOS。 FFmpeg 的主要组件包括: ffmpeg:这是一个命令行工…...

JavaCV 实现视频链接截取封面工具
引入必要依赖 <!--JavaCV--> <dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.7</version> </dependency> <dependency><groupId>cn.hutool</groupI…...

初识Linux · 进程替换
目录 前言: 1 直接看代码和现象 2 解释原理 3 将代码改成多进程版本 4 认识所有函数并使用 前言: 由前面的章节学习,我们已经了解了进程状态,进程终止以及进程等待,今天,我们学习进程替换。进程替换我…...

项目-坦克大战学习-人机ai
我们要知道,人机的移动和玩家的移动方式是一样的,所以我们可以将玩家移动代码以及检测碰撞代码移过来,唯一不同的就是人机检测到碰撞后会改变方向继续移动而不是停止 所以我们需要一个随机数使人机检测到碰撞后随机修改方向 Random rd new …...

YOLOv11改进 | Conv篇 | YOLOv11引入SKConv
1. SKConv介绍 1.1 摘要:在标准卷积神经网络(CNN)中,每层中阿尔蒂神经元的感受野被设计为共享相同的大小。在神经科学界众所周知,视觉皮层神经元的感受野大小受到刺激的调制,这在构建CNN时很少考虑。我们在CNN中提出了一种动态选择机制,允许每个神经元根据输入信息的多…...

招联2025校招内推
【投递方式】 直接扫下方二维码,或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus,使用内推码 igcefb 投递) 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策…...

美容院管理创新:SpringBoot系统设计与开发
摘 要 如今的信息时代,对信息的共享性,信息的流通性有着较高要求,因此传统管理方式就不适合。为了让美容院信息的管理模式进行升级,也为了更好的维护美容院信息,美容院管理系统的开发运用就显得很有必要。并且通过开发…...