Linux编程基础 8.4:epoll工作模式

1 简介

poll机制的工作原理及流程与select类似,但poll可监控的进程数量不受select中第二个因素——fd_set集合容量的限制,用户可在程序中自行设置被监测的文件描述符集的容量,当然poll在阻塞模式下也采用轮询的方式监测文件描述符集,因此应合理设置poll中监控进程的数量。

2 poll函数

poll()函数存在于函数库poll.h中,其声明如下:

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
  • 参数fds是一个struct pollfd类型的指针,主要用于传入被监测的多个文件描述符,其数据类型struct pollfd的定义如下:
struct pollfd{int fd;				//文件描述符,设置为-1时,表示取消对该文件描述符的监测short events;		//等待的事件short revents;		//实际发生的事件
}
                                         poll事件相关宏及其说明

在这里插入图片描述

  • 参数nfds等同于select()函数中的参数nfds,用来设置pollt监控的文件描述符的范围,需设置为文件描述符最大值加1;

  • 参数timeout与select()函数中的参数timeout,都用于设置组设时长,但其取值略有差异,poll()函数中参数timeout的取值及其对应含义如下:
    – 当timeout=-1时,poll()函数阻塞等待;
    – 当timeout=0时,poll()函数将立即返回,以轮询的方式监测文件描述符表;
    – 当timeout>0时,等待指定时长(单位为毫秒,若当前系统时间精度不够毫秒则向上取值)。

  • poll()函数若调用成功将返回就绪文件描述符数量;若等待超时,将返回0,表示没有已就绪的文件描述符;若调用出错,将返回-1,并设置errno。

【案例】:使用poll模型搭建多路I/O转接服务器,使服务器可接收客户端数据,并将接收到的数据转为大写,写回客户端;使客户端可向服务器发送数据,并将服务器返回的数据打印到终端。

poll_s.c					//服务器1#include <stdio.h>2#include <stdlib.h>3#include <string.h>4#include <netinet/in.h>5#include <arpa/inet.h>6#include <poll.h>7#include <errno.h>8#include "wrap.h"9#define MAXLINE 80						//缓冲数组大小10#define SERV_PORT 8000					//端口号11#define OPEN_MAX 1024					//最大打开文件描述符数量12int main()13{14	int i, j, maxi, listenfd, connfd, sockfd;15	int nready;16	ssize_t n;17	char buf[MAXLINE], str[INET_ADDRSTRLEN];18	socklen_t clilen;19	struct pollfd client[OPEN_MAX];		//文件描述符与事件集合20	struct sockaddr_in cliaddr, servaddr;21	listenfd = Socket(AF_INET, SOCK_STREAM, 0);22	bzero(&servaddr, sizeof(servaddr));23	servaddr.sin_family = AF_INET;24	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);25	servaddr.sin_port = htons(SERV_PORT);26	Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));27	Listen(listenfd, 20);28 	//初始化poll()的参数fds29	client[0].fd = listenfd;30	client[0].events = POLLRDNORM;	//设置listenfd监听普通读事件31	for (i = 1; i < OPEN_MAX; i++)32		client[i].fd = -1; 		//将client[]中其余元素的fd成员初始化为-133	maxi = 0; 					//记录client[]数组有效元素中最大元素下标34	//使用poll()机制循环检测文件描述符集合35 	for (;;) {36		nready = poll(client, maxi + 1, -1);	//阻塞等待请求到达37 		//通过listenfd状态判断是否有客户端连接请求,如有则建立连接38		if (client[0].revents & POLLRDNORM) {39			clilen = sizeof(cliaddr);40			connfd = Accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);41			printf("received from %s at PORT %d\n",42				inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),43				ntohs(cliaddr.sin_port));44 			//将accept返回的connfd存放到client[]中的空闲位置45			for (i = 1; i < OPEN_MAX; i++){46				if (client[i].fd < 0) {47					client[i].fd = connfd;48					break;49				}50 			}51			if (i == OPEN_MAX)52				perr_exit("too many clients");53			client[i].events = POLLRDNORM; 	//设置刚刚返回的connfd,监控读事件54			if (i > maxi)					//更新client[]中最大元素下标55				maxi = i;56			if (--nready <= 0) 				//若无就绪事件,回到poll阻塞57				continue;58		}59 		//检测client[],处理有就绪事件的文件描述符60		for (i = 1; i <= maxi; i++){61			if ((sockfd = client[i].fd) < 0)62				continue;63			if (client[i].revents & (POLLRDNORM | POLLERR)) {64				if ((n = Read(sockfd, buf, MAXLINE)) < 0) {65 					//比较errno,若为RST则表示连接中断66					if (errno == ECONNRESET){67						printf("client[%d] aborted connection\n", i);68						Close(sockfd);69						client[i].fd = -1;70					}71					else72						perr_exit("read error");73				}74				else if (n == 0) {//连接由客户端关闭75					printf("client[%d] closed connection\n", i);76					Close(sockfd);77					client[i].fd = -1;78				}79				else {//若成功读取数据,则对数据进行操作80					for (j = 0; j < n; j++)81						buf[j] = toupper(buf[j]);82					Writen(sockfd, buf, n);83				}84 				//当就绪文件描述符数量为0时,终止循环85				if (--nready <= 0)86					break; 87			}88		}89	}90	return 0;}
poll_c.c					//客户端1#include <stdio.h>2#include <string.h>3#include <unistd.h>4#include <netinet/in.h>5#include "wrap.h"6#define MAXLINE 80						//缓冲数组大小7#define SERV_PORT 8000					//端口号8int main()9{10	struct sockaddr_in servaddr;11	char buf[MAXLINE];12	int sockfd, n;13	sockfd = Socket(AF_INET, SOCK_STREAM, 0);14	bzero(&servaddr, sizeof(servaddr));15	servaddr.sin_family = AF_INET;16	inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);17	servaddr.sin_port = htons(SERV_PORT);18	Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));19	while (fgets(buf, MAXLINE, stdin) != NULL) {20		Write(sockfd, buf, strlen(buf));21		n = Read(sockfd, buf, MAXLINE);22		if (n == 0)23			printf("the other side has been closed.\n");24		else25			Write(STDOUT_FILENO, buf, n);26	}27	Close(sockfd);28	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/336665.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

相对位姿估计

相对位姿估计 示意图 理论推导 离线数据库&#xff1a; P的位置 P [ X , Y , Z ] T P[X,Y,Z]^{T} P[X,Y,Z]T 相机内参 k 1 k_{1} k1​ 安卓手机&#xff1a; 相机内参 k 2 k_{2} k2​ 两个像素点位置 &#xff1a; p 1 和 p 2 p_1和p_2 p1​和p2​ 公式一&#xff1a;…

Python魔法之旅-魔法方法(04)

目录 一、概述 1、定义 2、作用 二、主要应用场景 1、构造和析构 2、操作符重载 3、字符串和表示 4、容器管理 5、可调用对象 6、上下文管理 7、属性访问和描述符 8、迭代器和生成器 9、数值类型 10、复制和序列化 11、自定义元类行为 12、自定义类行为 13、类…

2年go蓝炎科技、爱诗科技面试经历,期望薪资22K

广州蓝炎科技一面 1、简单自我介绍&#xff1f;用的什么技术栈&#xff1f; 2、go的map是线程安全的吗&#xff1f; 3、Channel一般会在什么场景下使用&#xff1f;往一个未初始化的channel发送数据&#xff0c;会怎样&#xff1f; 4、关于go里头的随机数是线程安全的吗&am…

网卡配置基础知识

1、网络设置方式 首先科普下Virtual Box虚拟机的几种主流的网络设置方式&#xff0c;官方文档&#xff1a; 2解释 Host-only&#xff1a;仅主机模式 虚拟机和宿主机、虚拟机之间能互通&#xff0c;但是不能访问外网&#xff0c;虚拟机和宿主机同网段的其他主机不能互通这种…

VScode远程连接linux服务器开发,误删了文件怎么找回。

因为远程服务器大家都在用&#xff0c;没有足够权限去折腾。找遍了没找到方法&#xff0c;就告诉我远程的文件本地没有缓存啊&#xff01;我就差点开始重写代码了&#xff0c;后来被我发现了TIMELINE功能&#xff0c;这个功能真的好啊&#xff01;&#xff01;&#xff01;关键…

[算法] 优先算法(三):滑动窗口(上)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …

C++系列——————类和对象(上)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、面向对象的三大特征二、类的引入2.1类的定义 三.类的访问限定符3.1访问限定符的介绍3.2.访问限定符的使用 四、类的作用域五、类的实例化六、类对象模型6.1…

透视AI技术:探索折射技术在去衣应用中的奥秘

引言&#xff1a; 随着人工智能技术的飞速发展&#xff0c;其在图像处理和计算机视觉领域的应用日益广泛。其中&#xff0c;AI去衣技术作为一种颇具争议的应用&#xff0c;引发了广泛的讨论和关注。本文将深入探讨折射技术在AI去衣中的应用及其背后的原理。 一、AI去衣技术简介…

【C语言】探索文件读写函数的全貌

&#x1f308;个人主页&#xff1a;是店小二呀 &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;C笔记专栏&#xff1a; C笔记 &#x1f308;喜欢的诗句:无人扶我青云志 我自踏雪至山巅 &#x1f525;引言 本章将介绍文件读取函数的相关知识和展示使用场景&am…

Stable Diffusion AI绘画:从创意词汇到艺术图画的魔法之旅

文章目录 一、Stable Diffusion的工作原理二、从提示词到模型出图的过程三、Stable Diffusion在艺术创作中的应用《Stable Diffusion AI绘画从提示词到模型出图》内容简介作者简介楚天 目录前言/序言本书特色特别提示 获取方式 在科技的飞速发展中&#xff0c;Stable Diffusion…

贵州大学24计算机考研数据速览,国家重点实验室22408复试线285分!贵州大学计算机考研考情分析!

贵州大学计算机科学与技术学院坐落在贵州大学北校区&#xff08;贵阳花溪&#xff09;。 学院现有教职工139人&#xff0c;其中专职教师126人&#xff0c;教授17人&#xff0c;副教授37人&#xff0c;讲师46人&#xff0c;高级实验师4人&#xff0c;实验师17人。具有博士学位的…

订单共享模式:开启你的终身财富之旅

在当今这个信息爆炸的时代&#xff0c;每个人都在寻找着属于自己的财富增长之道。而“二人订单共享结束制”作为一种全新的商业模式&#xff0c;正以其独特的魅力吸引着越来越多的目光。只需499元的终身消费&#xff0c;你便能成为平台的会员&#xff0c;开启一段与众不同的赚钱…

OpenStack平台Nova管理

1. 规划节点 使用OpenStack平台节点规划 IP主机名节点192.168.100.10controller控制节点192.168.100.20compute计算节点 2. 基础准备 部署的OpenStack平台 1. Nova运维命令 &#xff08;1&#xff09;Nova管理安全组规划 安全组&#xff08;security group&#xff09;是…

MySQL导入SQL脚本---超详细介绍

1.新建xxx数据库&#xff0c;字符集选对。 2.在mysql安装目录下cmd进入小黑窗 3.执行mysql -uroot -p123456 --default-character-setutf8命令 4.use xxx; 5.source xxx.sql 执行完上面的命令等待结束就可以了 需要注意的是--default-character-setutf8&#xff0c;要不然可…

C++ 并发编程指南(13)线程状态及切换

文章目录 一、多线程状态及切换1、线程状态2、状态切换 前言&#xff1a; C中的线程状态及切换是操作系统和C线程库&#xff08;如POSIX线程或C11及之后的<thread>库&#xff09;共同管理的。线程的状态和切换是多线程编程中的重要概念&#xff0c;下面将简要介绍C线程的…

[排序算法]插入排序+希尔排序全梳理!

目录 1.排序是什么&#xff1f;1.1排序的概念1.2排序运用1.3常见的排序算法 2.插入排序分类3.直接插入排序基本思想具体步骤&#xff1a;动图演示代码实现直接插入排序的特性总结&#xff1a; 4. 希尔排序基本思想具体步骤动图演示代码实现希尔排序的特性总结&#xff1a; 5.总…

SpringBoot项目本地运行正常,jar包运行时前端报错403:No mapping for......

SpringBoot项目本地运行正常&#xff0c;jar包运行时前端报错403&#xff1a;No mapping for… 提示&#xff1a;在部署jar包到云服务器上之前&#xff0c;一定要在本地运行jar包&#xff0c;查看前端代码是否运行正常&#xff0c;若报错的话可以节省很多时间 方式&#xff1a;…

面向Java程序员的Go工程开发入门流程

对于一个像我这样没有go背景的java程序员来说&#xff0c;使用go开发一个可用的程序的速度是肉眼可见的缓慢。 其难点不在于go语言本身&#xff0c;而是搭建整个工程链路的过程&#xff0c;即所谓的“配环境”。 本文主要讲述如何配出一个适合go开发的环境&#xff0c;以免有同…

Spring 源码:深度解析AOP源码配置解析

文章目录 一、 解析AOP配置的入口1.1 从XML配置到AOP Namespace的解析流程1.2 分析注解驱动的AOP配置解析流程 二、AOP配置解析的核心流程2.1 ConfigBeanDefinitionParser 类2.2 parse()2.3 parseAdvisor()2.4 parseAspect()2.5 parsePointcut()2.6 createAdvisorBeanDefinitio…

[C#]使用C#部署yolov8的obb旋转框检测tensorrt模型

【测试通过环境】 win10 x64 vs2019 cuda11.7cudnn8.8.0 TensorRT-8.6.1.6 opencvsharp4.9.0 .NET Framework4.7.2 NVIDIA GeForce RTX 2070 Super 版本和上述环境版本不一样的需要重新编译TensorRtExtern.dll&#xff0c;TensorRtExtern源码地址&#xff1a;TensorRT-CShar…