poll()系统调用

news/2024/11/8 14:43:13/
#include <poll.h>
int poll(struct pollfd fds[], nfds_t nfds, int timeout);Returns number of readf file descriptors, 0 on timeout, or -1 on error.

参数fds列出了我们需要poll()来检查的文件描述符。该参数为pollfd结构体数组,其定义如下:

struct pollfd{int fd;short events;short revents;
};

参数nfds指定了数组fds中元素的个数。数据类型nfds_t实际为无符号整型。

pollfd结构体中的eventsrevents字段都是位掩码。调用者初始化events来指定需要为描述符fd做检查的事件。

poll()返回时,revents被设定以此来表示该文件描述符上实际发生的事件。

下表列出了可能会出现在eventsrevents字段中的位掩码。

  • 该表中第一组位掩码(POLLIN, POLLRDNORM, POLLRDBAND, POLLPRI以及POLLRDHUP)同输入事件相关。

  • 下一组掩码(POLLOUT, POLLWRNORM 以及 POLLWRBAND)同输出事件相关。

  • 第三组掩码(POLLERR, POLLHUP 以及 POLLNVAL)是设定在revents字段中用来返回有关文件描述符的附加信息。如果在events中指定了这些位掩码,则者三位将被户卤鹅。

  • 在Linux系统中,poll()不会用到最后一个位掩码POLLMSG

位掩码events中的输入返回到revents描述
POLLIN可读取非高优先级的数据
POLLRDNORM等同于POLLIN
POLLRDBAND可读取优先级数据(Linux中不使用)
POLLPRI可读取高优先级数据
POLLRDHUP对端套接字关闭
——————————————————————————————————
POLLOUT普通数据可写
POLLWRNORM等同于POLLOUT
POLLWRBAND优先级数据可写入
——————————————————————————————————
POLLERR有错误发生
POLLHUP出现挂断
POLLNVAL文件描述符未打开|
——————————————————————————————————
POLLMSGLinux中不使用(SUSv3中未指定) |

如果我们对某个特定的文件描述符上的事件不感兴趣,可以将events设为0。
另外,给fd字段指定一个负值(例如,如果值为非零,取它的相反数)将导致对应的events字段被忽略,且revents字段将总是返回0.

这两种方法都可以用来(也许只是暂时的)关闭单个文件描述符的检查,而不需要重新建立整个fds列表。

下面列出的是关于poll()的Linux实现:

  • POLLINPOLLRDNORM是同义词。
  • POLLIUTPOLLWRNORM是同义词。
  • 一般来说,POLLRDBAND是不被使用的,也就是说它在events字段中被忽略,也不会被设定到revents字段中去。

唯一用到POLLRDBAND的地方是在实现DECnet网络协议的代码中(已过时)。

  • 必须定义_XOPEN_SOURCE测试宏,这样才能在头文件<poll.h>中得到常量POLLRDNORMPOLLRDBANDPOLLWRNORM以及POLLWRBAND的定义。
  • POLLRDHUP是Linux专有的标志位。要在头文件<poll.h>中得到它,必须定义_GNU_SOURCE测试宏。
  • 如果指定的文件描述符在调用poll()时关闭了,则返回POLLNVAL

总结以上要点,poll()真正关心的标志位就是POLLINPOLLOUTPOLLPRIPOLLRDHUPPOLLHUP以及POLLERR

timeout参数

参数timeout决定了poll()的阻塞行为,具体如下:

  • 如果timeout 等于 -1poll()一直阻塞直到 fds数组中列出的文件描述符有一个达到就绪态(定义在对应的events 字段中)或者捕获到一个信号。
  • 如果timeout等于0,poll()不会阻塞——只是执行一次检查看看哪个文件描述符处于就绪态。
  • 如果timeout大于0,poll()至多阻塞timeout毫秒,直到fds列出的文件描述符中有一个达到就绪态,或者直到捕获到一个信号为止。

poll()的返回值

  • 返回-1表示有错误发生。一种可能的错误是EINTR,表示该调用被一个信号处理例程中断。 (poll()绝对不会自动恢复)
  • 返回0表示该调用在任意一个文件描述符称为就绪态之前就超时了。
  • 返回正整数表示有一个或多个文件描述符处于就绪态了。返回值表示数组fds中拥有非零revents字段的pollfd结构体数量。

注意select()poll()返回正整数时的细小差别。
如果一个文件描述符在返回的描述符集中出现了不止依次,select()会将同一个文件描述符计数多次。
poll()返回的是就绪的文件描述符个数,且一个文件描述符只会统计一次,就算在相应的revents字段中设定了多个位掩码也是如此。

补充

  1. 在描述符数量很多时,poll()效率比select()性能明显更好。
  2. poll()select()在大多数系统上不会自动重启,SA_RESTART选项对它们不起作用(见APUE第3版p409)。

参考书籍

  1. UNIX环境高级编程 第3版
  2. Linux/UNIX系统编程手册

http://www.ppmy.cn/news/64068.html

相关文章

【C++】继承和多态、public、private、protected、重写

区分继承与多态、辨别public、protected、private 继承与多态的概念继承与多态的区别与联系区别&#xff1a;联系&#xff1a;示例结果&#xff1a; 继承和访问的权限说明示例&#xff1a;结果 结论 继承与多态的概念 面向对象三大原则&#xff1a;封装、继承、多态。继承是一种…

面向开发人员的 ChatGPT 提示词教程 - ChatGPT Prompt Engineering for Developers

面向开发人员的 ChatGPT 提示词教程 - ChatGPT Prompt Engineering for Developers 1. 指南(原文: Guidelines)1-1. 提示的指南(原文: Guidelines for Prompting)1-2. 配置1-3. 提示语原则(原文: Prompting Principles)原则 1: 写出清晰而具体的指示(原文: Write clear and spe…

【LeetCode】《LeetCode 101》第七章:动态规划

文章目录 7.1 算法解释7.2 基本动态规划&#xff1a;一维70. 爬楼梯&#xff08;简单&#xff09;198.打家劫舍&#xff08;中等&#xff09;413. 等差数列划分&#xff08;中等&#xff09; 7.3 基本动态规划&#xff1a;二维64. 最小路径和&#xff08;中等&#xff09;542. …

多项式指数函数(多项式 exp)

板题&#xff1a;P4726 【模板】多项式指数函数&#xff08;多项式 exp&#xff09; 已知 g ( x ) g(x) g(x)&#xff0c;你要求出 f ( x ) ≡ e g ( x ) ( m o d x n ) f(x)\equiv e^{g(x)} \pmod{x^n} f(x)≡eg(x)(modxn)。 前置知识&#xff1a;多项式求逆&#xff0c;…

C++ MFC调用JS代码获取返回值

C有时候会需要调用JS代码&#xff0c;这对于C来说或者对于国内来说一直是比较蛋疼的问题&#xff0c;主要是资料少&#xff0c;微软提供了一个COM组件&#xff0c;里面包含有JS引擎&#xff0c;这个组件就是&#xff1a;msscript.dll。 此文件在C:\Windows\SysWOW64目录下&…

webpack 5 实战(3)

四十一、代码拆分方式 通过Webpack实现前端项目整体模块化的优势很明显&#xff0c;但是它同样存在一些弊端&#xff0c;那就是项目当中所有的代码最终都会被打包到一起&#xff0c;试想一下&#xff0c;如果说应用非常复杂&#xff0c;模块非常多的话&#xff0c;那打包结果就…

有哪些入耳舒服的蓝牙耳机?公认佩戴舒适度最高蓝牙耳机

数码科技市场日益发展的更加智能化&#xff0c;日常所接触到的各类产品都开始往智能化发展&#xff0c;鲜为人知的蓝牙耳机一直是不过时的&#xff0c;因为小巧易携带深受大众喜欢&#xff0c;下面整理了几款佩戴舒适的蓝牙耳机给大家。 一、南卡小音舱Lite2蓝牙耳机 售价&am…

spi 设备注册分析

/* * spi 设备注册分析 */ 1. kernel/drivers/spi/spi.c 初始化设备 device_initialize /* 调用device_initialize 的会有这些函数 */ spi_match_controller_to_boardinfo spi_new_device spi_alloc_devi…