slect( )、poll( )、epoll( )函数详解

2023-11-16

1、slect()函数

1.1、函数原型

	#include  <sys/time.h>

	int select(int maxfdp, fd_set* readfds, fd_set* writefds, fd_set* errorfds, struct timeval* timeout);

(1)maxfdp:指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错;
(2)readfds:要监视读操作的文件描述符集合;
(3)writefds:要监视写操作的文件描述符集合;
(4)errorfds:要监视出错操作的文件描述符集合;
(5)timeout:函数返回超时;
(6)返回值:负值–出错,0–超时返回,正值–有文件可读,或可写,或可读可写;
补充:fd_set有专门的宏来操作,不必深究细节;

1.2、timeout值说明

struct timeval
	{      
        long tv_sec;   /*秒 */
        long tv_usec;  /*微秒 */
    }

1.3、struct fd_set集合的操作宏

FD_ZERO(fd_set*);        //清空集合,相当于memset

FD_SET(int, fd_set*);    //将一个给定的文件描述符加入集合之中

FD_CLR(int,   fd_set*);  //将一个给定的文件描述符从集合中删除

FD_ISSET(int, fd_set*);  //检查集合中指定的文件描述符是否可以读写

1.4、示例代码

	int status = -1;
	fd_set fds_r;
	fd_set fds_w;
	
	//将集合清零
	FD_ZERO(&fds_r);
	FD_ZERO(&fds_w);
	
	//文件描述符fd1添加到读监视集合
	FD_SET(fd1,&fds_r); 
	
	//文件描述符fd1添加到写监视集合
	FD_SET(fd2,&fds_w); 
	
	//文件描述符的最大值加1
	maxfdp=fd1>fd2 ? fd1+1 : fd2+1;
	
	//监视集合中的文件描述符,直到有文件可读会可写才返回
	status = select(maxfdp,&fds_r, &fds_w, NULL, NULL)
	if(status <= 0)
	{
		//出错,什么也不做
	}
	else	//说明有文件描述符可读或者可写,需要轮询式的查询所有监视的文件描述符集合
	{
		if (FD_ISSET(fd1,&fds_r))
		{
			read(fd1, buf, size);
		}
		 
		if (FD_ISSET(fd2,&fds_w))
		{
			write(fd2, buf, size);
		}
	}

2、poll()函数

2.1、函数原型

	#include <poll.h>

	int poll(struct pollfd fd[], nfds_t nfds, int timeout);

(1)fd:是一个struct pollfd数组,保存要监控的文件描述符信息;
(2)nfds:要监视的文件描述符的数据;
(3)timeout:超时时间,单位是毫秒;
(4)返回值:要么超时返回,要么阻塞住;返回值n>0时,表示有n个文件描述符发生了相应的事件;

2.2、timeout值说明

(1)INFTIM:永远等待,阻塞住;
(2)0:立即返回,不阻塞进程;
(3)>0:阻塞指定时间后返回;

2.3、struct pollfd结构体

 struct pollfd{

	  int fd; //要监视的文件描述符

	  short events; //要监视fd将发生的事件

	  short revents; //poll函数返回时,fd发生的的事件

  };

2.4、事件标志

	POLLIN 普通或优先级带数据可读
	POLLRDNORM 普通数据可读
	POLLRDBAND 优先级带数据可读
	POLLPRI 高优先级数据可读
	POLLOUT 普通数据可写
	POLLWRNORM 普通数据可写
	POLLWRBAND 优先级带数据可写
	POLLERR 发生错误
	POLLHUP 发生挂起
	POLLNVAL 描述字不是一个打开的文件

常用的是POLLIN(可读)和POLLOUT(可写);

2.5、示例代码

	//要监控的文件描述符数量
	int fdCnt = 2; 
	
	//申请保存文件描述符的struct pollfd结构体
	struct pollfd *pollfd;	
	pollfd = (struct pollfd*)calloc(fdCnt, sizeof(struct pollfd));

	//fd1文件描述符监视是否可读
	pollfd[0].fd = fd1;
	pollfd[0].events = POLLIN;

	//fd2文件描述符监视是否可写
	pollfd[1].fd = fd2;
	pollfd[1].events = POLLOUT;
	
	//监视文件描述符并且阻塞,知道有文件描述符发生相应的事件
	numready = poll(pollfd, fdCnt, INFTIM);
	
	//轮询监视的文件描述符
	for(i=0; i< numready && fdCnt > 0; i++)
	{
		if(pollfd[i].revents & POLLIN)
		{
			read(pollfd[i].fd, buf, size)
			i++;
		}
		
		if(pollfd[i].revents & POLLIN)
		{
			write(pollfd[i].fd, buf, size)
			i++;
		}
		
		fdCnt--;
	}

3、epoll()函数

3.1、epoll_create()函数

//创建一个epoll对象,同时返回该对象的描述符
int epoll_create(int size);

(1)size:要监听的文件描述符的数量;
(2)返回值:创建的epoll对象描述符;

3.2、epoll_ctl()函数

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

(1)epfd:epoll_create()函数返回的epoll对象描述符;
(2)op:本次的操作;
(3)fd:要监听的文件描述符;
(4)event:关联要监听的fd,里面会对要监听的fd进行设置;

3.3、参数op

含义
EPOLL_CTL_ADD 将参数 fd 指定的描述符添加到 epoll 对象中,同时将其关联到一个 epoll 事件对象——即参数 event 所指定的值
EPOLL_CTL_MOD 修改描述符 fd 所关联的事件对象 event,前提是该 fd 已经添加到了 epoll 对象中
EPOLL_CTL_DEL 将描述符 fd 从 epoll 对象中移除,此时参数 event 被忽略,也可指定为 NULL

3.4、fd监听的事件

含义
EPOLLIN 监听 fd 是否可读
EPOLLOUT 监听 fd 是否可写
EPOLLRDHUP Linux 2.6.17 后可用。监听流式套接字对象是否关闭或半关闭
EPOLLPRI 监听是否有紧急数据可读

3.5、struct epoll_event结构体

typedef union epoll_data {
  void        *ptr;
  int          fd;	//监听的文件描述符fd
  uint32_t     u32;
  uint64_t     u64;
} epoll_data_t;

struct epoll_event {
  uint32_t     events;      /* fd要监听的事件 */
  epoll_data_t data;        /* 用户数据,和fd绑定 */
};

(1)events:fd要监听的事件;
(2)data:fd绑定的数据,将来epoll_wait()函数返回发生事件的fd时,会返回fd绑定的epoll_data_t结构体数据;

3.6、epoll_wait()函数

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

(1)epfd:epoll_create()函数返回的epoll对象描述符;
(2)events:外部定义的一个struct epoll_event结构体数据,将地址传进去,epoll_wait()函数在返回时会将发生
事件的fd信息填充到该结构体中;
(3)maxevents:告诉epoll_wait()函数,events数组有几个成员;
(4)timeout:超时时间;

3.7、示例代码

//创建epoll对象,最多监听4个文件描述符
int  epfd = epoll_create(4);

struct epoll_event ev;
ev.data.fd = fd1; // 注意这个值必须要指定,不然 epoll_wait 返回了你也不知道是谁发生了事件
ev.events = EPOLLIN; // 想监听可读事件,因为没有指定 EPOLLET 选项,所以默认是水平触发
epoll_ctl(epfd, EPOLL_CTL_ADD, fd1, &ev);

ev.data.fd = fd2; // 注意这个值必须要指定,不然 epoll_wait 返回了你也不知道是谁发生了事件
ev.events = EPOLLOUT; // 想监听可写事件,因为没有指定 EPOLLET 选项,所以默认是水平触发
epoll_ctl(epfd, EPOLL_CTL_ADD, fd2, &ev);

 // 事件数组 evts 用来保存 epoll_wait 返回的事件
 struct epoll_event evts[4];
  
// 开始等待事件发生,res 表示发生了事件的个数
int res = epoll_wait(epfd, evts, 4, -1);

// 开始处理所有事件
for (i = 0; i < res; ++i) {
  // 这个 fd 就是你一开始通过 event 的 data 成员传进去的。
  fd = evts[i].data.fd;
  if (evts[i].events & EPOLLIN) {
    	//读文件描述符
  }
   if (evts[i].events & EPOLLOUT) {
   		//写文件描述符
   }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

slect( )、poll( )、epoll( )函数详解 的相关文章

  • 除了 iptables 之外还有数据包管理实用程序吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 Linux 实用程序 它可以根据一组规则更改网络数据包的有效负载 理想情况下 我会使用
  • 编译器 libstdc++ 版本与系统版本

    我试图了解 g 如何选择它链接的 libstdc 版本 以及当库的 系统 版本不同时它意味着什么 我正在使用 gcc g 4 1 2 根据ABI 指南 http gcc gnu org onlinedocs libstdc manual a
  • 将用户添加到组但运行“id”时未反映

    R 创建了一个名为 Staff 的组 我希望能够在不以 sudo 身份启动 R 的情况下更新软件包 所以我使用以下方法将自己添加到员工中 sudo usermod G adm dialout cdrom plugdev lpadmin ad
  • 命令行参数中的“-”(破折号)有什么魔力?

    例子 创建 ISO 映像并将其直接刻录到 CD mkisofs V Photos r home vivek photos cdrecord v dev dev dvdrw 更改到上一个目录 cd 侦听端口 12345 并解压发送到该端口的数
  • 如何随时暂停 pthread?

    最近我开始将 ucos ii 移植到 Ubuntu PC 上 我们知道 在pthread的回调函数中的 while 循环中简单地添加一个标志来执行暂停和恢复是不可能模拟ucos ii中的 进程 的 如下解决方案 因为ucos ii中的 进程
  • 使用 linux perf 工具测量应用程序的 FLOP

    我想使用 perf Linux 性能计数器子系统的新命令行接口命令 来测量某些应用程序执行的浮点和算术运算的数量 出于测试目的 我使用了我创建的一个简单的虚拟应用程序 请参见下文 因为我找不到任何为测量 FP 和整数运算而定义的 perf
  • Linux shell 命令逐块读取/打印文件

    是否有一个标准的 Linux 命令可以用来逐块读取文件 例如 我有一个大小为 6kB 的文件 我想读取 打印第一个 1kB 然后是第二个 1kB 看来猫 头 尾在这种情况下不起作用 非常感谢 你可以这样做read n在循环中 while r
  • 当我通过 shell 脚本创建 .txt 文件时,为什么文件名末尾出现问号? [复制]

    这个问题在这里已经有答案了 我正在编写一个 shell 脚本 我应该在其中创建 1 个文本文件 当我这样做时 文件名末尾出现一个问号 是什么原因 我正在 bash 脚本中尝试以下方法 1 grep ERROR a1 gt text txt
  • sed 仅最后一个匹配模式

    我想sed仅文本文件的最后一个匹配模式 输入文件 boy boy girl boy 输出文件 boy boy girl boys 一种方法是反转文件 仅替换第一个匹配项 然后再次反转 tac
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • 在64位操作系统上以32位模式和64位模式编译ioctl函数的执行有什么不同?

    我有 64 位 Enterprise SuSE 11 我有一个应用程序 它打开 HIDRAW 设备并在其上操作 ioctl 函数以从该设备获取原始信息 如下所示 struct hidraw devinfo devinfo int fd op
  • Bash 中 $() 和 () 之间的区别

    当我打字时ls l echo file 支架的输出 这只是简单的回显 被获取并传递到外部ls l命令 就等于简单的ls l file 当我打字时ls l echo file 我们有错误 因为不能嵌套 内部外部命令 有人可以帮助我理解之间的区
  • 是否可以找到哪个用户位于 localhost TCP 连接的另一端?

    这是一个编程问题 但它是 Linux Unix 特定的 如果我从本地主机获得 TCP 连接 是否有一种简单的方法可以告诉哪个用户在 C 程序内建立了连接而无需 shell 我知道这对于 Unix 域套接字来说并不太难 我已经知道远程 IP
  • Alsa 带有来自调制解调器的 PCM 接口

    我有一个基于 imx28 CPU 的定制板 CPU 的串行端口连接到调制解调器的 PCM 输出 我必须为调制解调器的 PCM 接口开发一个驱动程序 使其成为 ALSA SoC 的一部分 您能指出内核树 中与我的设置重新组合的一些驱动程序吗
  • 无法为 Python 3.4 创建工作虚拟环境

    I 安装Python 3 4 2 https docs python org 3 using unix html building python和我的 Linux Mint 17 1 中的 Virtualenv 12 0 5 然后我尝试创建
  • 如何在 Linux 中使用单行命令获取 Java 版本

    我想通过单个命令获取 Linux 中的 Java 版本 我是 awk 的新手 所以我正在尝试类似的事情 java version awk print 3 但这不会返回版本 我将如何获取1 6 0 21从下面的Java版本输出 java ve
  • 如何在两个不同帐户之间设置无密码身份验证

    我们可以在两台机器的两种不同用途之间设置无密码身份验证吗 例如 计算机A有用户A 计算机B有用户B 我们可以设置密码 ssh 以便计算机 A 上的用户 A 使用其用户帐户 A 登录计算机 B 谢谢你 如果我理解你的问题 你能设置一下吗ssh
  • 编写多个mysql脚本

    是否可以在复合脚本中包含其他 mysql 脚本 理想情况下 我不想为包含的脚本创建存储过程 对于较大的项目 我想分层维护几个较小的脚本 然后根据需要组合它们 但现在 我很乐意学习如何包含其他脚本 source是一个内置命令 您可以在 MyS
  • 如何仅将整个嵌套目录中的头文件复制到另一个目录,在复制到新文件夹后保持相同的层次结构

    我有一个目录 其中有很多头文件 h 和其他 o 和 c 文件以及其他文件 这个目录里面有很多嵌套的目录 我只想将头文件复制到一个单独的目录 并在新目录中保留相同的结构 cp rf oldDirectory newDirectory将复制所有
  • 使用命令行将 MediaWiki 维基文本格式转换为 HTML

    我倾向于编写大量文档 因此 MediaWiki 格式对我来说很容易理解 而且比编写传统 HTML 节省了我很多时间 然而 我也写了一篇博客 发现一直从键盘切换到鼠标来输入正确的 HTML 标签会增加很多时间 我希望能够使用 Mediawik

随机推荐

  • react 事件监听

    react事件监听 在react js里监听事件很容易 需要给被监听的事件元素加上属性类似于onclick onkeydown这样的属性 例如我们现在要给title 加上点击时间的监听 class Title extends Compone
  • 懒人神器:自动生成单元测试插件 Squaretest

    你是否常常因代码需编写单元测试而痛苦不堪 你是否因单元测试历史债而惆怅不断 Squaretest或许能帮你消除痛苦消除惆怅 前言 一 Squaretest是什么 二 使用步骤 1 引入插件 2 使用步骤 总结 背景 近来公司增加了代码质量门
  • Matlab_牛顿迭代法解非线性方程

    例 用牛顿迭代法 取x初值为1 5 解算非线性方程 x 3 x 1 0 的根 程序代码 manewton m function x manewton fun dfun x0 ep N if nargin lt 5 N 500 end if
  • matlab画一个正弦函数y=sin(x)(全网最简便,没有之一)

    本博日常打卡 x 0 pi 100 2 pi y sin x plot x y plottools 说明 plottools on 按照您上次使用时的布局在当前图窗上显示图窗选项板 绘图浏览器和属性编辑器 不带参数的 plottools 与
  • live reload enabled是什么意思_老外说“Pigheaded”什么意思?猪头三?才不是

    最近 猪肉价格 一路飞涨 老妈买完菜 每天都在唠唠叨叨 今天排骨又涨了xx块钱 五花肉又涨了xx 邻居家长里短 聊得都是 猪肉 简直像小猪佩奇花一亿买了 小区热搜榜 似的 所以 小编就想着倒腾一篇 猪猪 相关的英语知识 分享给大家 咳咳 蹭
  • 初级5 题目一 认识哈希函数和哈希表

    1 哈希函数的定义及性质 1 哈希函数是函数 所以接收一个变量 返回一个值 接收的变量 其定义域理论上是无穷大 返回的值是哈希值 也就是每个变量都能生成对应的哈希值 2 哈希函数的值域是有穷的 哈希值有穷个 并非无穷大 哈希函数相当于把无穷
  • 作用域&内存空间

    作用域 C 语言编译器可以确认 4 种不同类型的作用域 代码块作用域 文件作用域 原型作用域和函数作用域 文件作用域 全局变量 函数名 链接属性 简单的来说 编译器将你的源文件变成可执行程序需要经过两个步骤 编译和链接 编译过程主要是将你写
  • nginx基本介绍(安装、常用命令、反向代理)

    文章目录 引言 一 nginx是什么 二 nginx的下载和安装 1 下载 2 windows下安装 3 运行 4 外部服务器无法访问问题 三 nginx的常用命令 四 nginx config 五 FileZilla 1 什么是FileZ
  • 数字证书 X509详解 && python解析SSL证书

    数字证书 数字证书就是互联网通讯中标志通讯各方身份信息的一系列数据 提供了一种在Internet上验证您身份的方式 其作用类似于司机的驾驶执照或日常生活中的身份证 它是由一个由权威机构 CA机构 又称为证书授权 Certificate Au
  • C++模板实参类型推导

    1 什么是模板 C 特性之一 批量生成代码的手段 2 模板有什么应用 1 泛型编程 例如 std vector 2 模板元编程 利用模板的特化等特性 在编译期计算出结果 例如 3 模板实参类型推导 虽然模板这么牛逼 但是今天我们不讲上述两个
  • 【华为OD统一考试B卷

    在线OJ 已购买本专栏用户 请私信博主开通账号 在线刷题 运行出现 Runtime Error 0Aborted 请忽略 华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一
  • 解决pip更新问题.WARNING: You are using pip version 19.2.3, however version 20.2.1 is available.

    一开始遇到这个问题在网上找了很多发现解决不了问题的根本 一开始我以为是网络的问题 后来一直是这样 然后有大佬告诉我你可能python版本太高了 他说卸载了换3 7的 3 8的很多功能都用不了 不过这样是很麻烦的 因为之前也安装了一些库 如果
  • 云服务器上Wamp搭建网站

    说明 想要在云服务器搭建网站 且需要被外网访问浏览的苦逼程序员可以参考本文 前提是你已经购买好了服务器以及公网IP 近一个月买了3次服务器 使用wamp搭建了3次网站了 本以为最后一次会轻车熟路 但是东搞西搞还是花了1个多小时 看来还是要把
  • (附源码)python+mysql+基于协同过滤算法的书籍推荐 毕业设计101555

    摘 要 21世纪的今天 随着社会的不断发展与进步 人们对于信息科学化的认识 已由低层次向高层次发展 由原来的感性认识向理性认识提高 管理工作的重要性已逐渐被人们所认识 科学化的管理 使信息存储达到准确 快速 完善 并能提高工作管理效率 促进
  • “晓白”学python-科普篇(3)-那些和python相关的岗位之python-web开发工程师

    老袁啊 python有这么广泛的应用 那我学好python能不能找到一份和python相关的工作呢 晓白问道 老袁听了回答道 你这个问题太笼统了 实际上你想问的是两个问题 一个就是那个工作岗位和python是相关的 第二个就是这些工作岗位对
  • nginx 正向代理 配置 http 和 https

    nginx 正向代理 配置 http 和 https 应用场景 同学A 所在公司对外网有所限制 借助云服务器nginx正向代理 实现正常浏览公网资料 服务端 云服务器 安装nginx cd usr local wget http nginx
  • Vue3内置组件teleport详解

    teleport的作用 该组件可以将指定内容渲染到特定容器中 而不受 DOM 层级的限制应用场景 当蒙层内容在一个组件中时 蒙层内容是无法遮挡住全部内容的 因此 需要使用teleport将蒙层内容渲染到更全局的组件中 如果不使用telepo
  • python入门(二)——数据类型

    目录 一 数字类型 二 字符串 例题1 凯撒密码 例题2 星号三角形 三 time模块 人家说合格的程序员要养成经常写博客的习惯 嗯 我正在培养中 日积月累 希望自己能坚持下去 一 数字类型 1 整数 与往常的C C 等语言的不同是 pyt
  • python为什么没有指针_Python的指针:有什么意义?

    Python部落 python freelycode com 组织翻译 禁止转载 欢迎转发 目录为什么Python没有指针 Python中的对象 不可变对象和可变对象 了解变量C的变量 Python的名称 关于Python的预实现对象的注释
  • slect( )、poll( )、epoll( )函数详解

    1 slect 函数 1 1 函数原型 include