poll方法的基本概念
一、select函数简单回顾
在上篇博客中,我们详细了解了关于select接口的用法,在学习poll函数之前,我们先对select函数的内容做一个简单的回顾:
select优点:
目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点
select缺点:
(1)每次调用 select(),都需要把 fd 集合从用户态拷贝到内核态,这个开销在 fd 很多时会很大,同时每次调用 select() 都需要在内核遍历传递进来的所有 fd,这个开销在 fd 很多时也很大。
(2)单个进程能够监视的文件描述符的数量存在最大限制,在 Linux 上一般为 1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但是这样也会造成效率的降低
(3)select函数在每次调用之前都要对参数进行重新设定,这样做比较麻烦,而且会降低性能
二、poll函数的基本概念
1、什么是poll?
select() 和 poll() 系统调用的本质一样,poll() 的机制与 select() 类似,与 select() 在本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理。
2、函数原型
参数解释:
(1)fds:指向一个结构体数组的第0个元素的指针,每个数组元素都是一个struct pollfd结构,用于指定测试某个给定的fd的条件
(2)nfds:表示fds结构体数组的长度
(3)timeout:表示poll函数的超时时间,单位是毫秒
函数功能:
监视并等待多个文件描述符的属性变化
函数返回值:
(1)返回值小于0,表示出错
(2)返回值等于0,表示poll函数等待超时
(3)返回值大于0,表示poll由于监听的文件描述符就绪返回,并且返回结果就是就绪的文件描述符的个数。
在该函数的第一个参数中,我们知道存放文件描述符的数组中每一个元素都是一个struct pollfd结构,那么pollfd结构到底是什么样的呢?我们来一起了解一下:
3、pollfd结构
结构体内容:
成员变量说明:
(1)fd:每一个 pollfd 结构体指定了一个被监视的文件描述符,可以传递多个结构体,指示 poll() 监视多个文件描述符。
(2)events:表示要告诉操作系统需要监测fd的事件(输入、输出、错误),每一个事件有多个取值
(3)revents:revents 域是文件描述符的操作结果事件,内核在调用返回时设置这个域。events 域中请求的任何事件都可能在 revents 域中返回。
events&revents的取值如下:
事件 | 描述 | 是否可作为输入(events) | 是否可作为输出(revents) |
---|---|---|---|
POLLIN | 数据可读(包括普通数据&优先数据) | 是 | 是 |
POLLOUT | 数据可写(普通数据&优先数据) | 是 | 是 |
POLLRDNORM | 普通数据可读 | 是 | 是 |
POLLRDBAND | 优先级带数据可读(linux不支持) | 是 | 是 |
POLLPRI | 高优先级数据可读,比如TCP带外数据 | 是 | 是 |
POLLWRNORM | 普通数据可写 | 是 | 是 |
POLLWRBAND | 优先级带数据可写 | 是 | 是 |
POLLRDHUP | TCP连接被对端关闭,或者关闭了写操作,由GNU引入 | 是 | 是 |
POPPHUP | 挂起 | 否 | 是 |
POLLERR | 错误 | 否 | 是 |
POLLNVAL | 文件描述符没有打开 | 否 | 是 |
注意:
每个结构体的 events 域是由用户来设置,告诉内核我们关注的是什么,而 revents 域是返回时内核设置的,以说明对该描述符发生了什么事件
4、socket就绪条件
与select中socket就绪条件一致:
读就绪:
1)socket内核中,接收缓冲区中的字节数,大于等于低水位标记SO_RCVLOWAT. 此时可以无阻塞的读该文件描述符, 并且返回值大于0;
2)socket TCP通信中, 对端关闭连接, 此时对该socket读, 则返回0;
3)监听的socket上有新的连接请求;
4)socket上有未处理的错误;
写就绪:
1)socket内核中, 发送缓冲区中的可用字节数(发送缓冲区的空闲位置大⼩), 大于等于低水位标记 SO_SNDLOWAT, 此时可以无阻塞的写, 并且返回值大于0;
2)socket的写操作被关闭(close或者shutdown). 对一个写操作被关闭的socket进行写操作, 会触发 SIGPIPE信号;
3)socket使⽤非阻塞connect连接成功或失败之后;
4)socket上有未读取的错误;
异常就绪:
socket上收到带外数据.
三、poll函数示例
使用poll函数监控标准输入:
用poll监控标准输入是因为当没有输入的时候,进程就一直处于阻塞状态,当有数据输入时时间就立即就绪,如果监听标准输出,由于写缓冲区比较大,可能一直处于就绪状态,不利于观察。
程序代码:
1 #include<stdio.h>2 #include<unistd.h>3 #include<poll.h>4 5 int main()6 {7 struct pollfd poll_fd;8 poll_fd.fd=0;9 poll_fd.events=POLLIN;10 11 for(;;)12 {13 int ret=poll(&poll_fd,1,2000);14 if(ret<0)15 {16 perror("poll");17 continue;18 }19 if(ret==0)20 {21 printf("poll timeout!\n");22 continue;23 }24 if(poll_fd.revents==POLLIN)25 {26 char buf[1024];27 read(0,buf,sizeof(buf)-1);28 printf("sdin:%s",buf);29 }30 }31 }
运行结果:
当没有输入时,进程处于阻塞状态(每两秒输出一条poll timeout语句):
当有输入时,系统会告诉用户事件就绪,进行输入工作,即有输入时就打印到屏幕上:
四、poll函数的优缺点
通过poll函数的结构以及小测试程序的编写,我们不难发现poll函数的一些特点:
1、优点
(1)poll() 不要求开发者计算最大文件描述符加一的大小。
(2)poll() 在应付大数目的文件描述符的时候速度更快,相比于select。
(3)它没有最大连接数的限制,原因是它是基于链表来存储的。
(4)在调用函数时,只需要对参数进行一次设置就好了
2、缺点
(1)大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。
(2)与select一样,poll返回后,需要轮询pollfd来获取就绪的描述符,这样会使性能下降
(3)同时连接的大量客户端在一时刻可能只有很少的就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降
poll方法的基本概念相关推荐
- java poll()是什么方法,JAVA学习中的一点小发现:LinkedList中.poll()方法在输出时使用应注意的小点...
在学习JAVA类集一章中关于LinkedList子类中.poll()方法易错点的分析心得 例如如下代码: package Test; import java.util.LinkedList; publ ...
- Linux一个驱动管理多个设备,poll方法(select多路监控原理与实现)
1.什么是Poll方法,功能是什么? 2.Select系统调用(功能) Select系统调用用于多路监控,当没有一个文件满足要求时,select将阻塞调用进程. int select(int maxf ...
- Queue接口分析:add和offer区别,remove和poll方法到底啥区别
往队列中添加元素有两个方法,分布是add和offer方法,两者的入参和返回值都一样,或许很多同学都奇怪,为什么,要有这两个功能类似(都是添加元素),但方法名不一样的方法,看看源码的注释 以下为Queu ...
- java的poll方法_Java中的队列poll()方法示例
使用poll()方法获取并删除Queue中的第一个元素. 创建一个队列-Queue q = new LinkedList(); 添加一些元素-q.add("abc"); q.add ...
- java linkedlist poll_Java LinkedList poll()方法
Java LinkedList poll()方法 java.util.LinkedList.poll() 检索并删除LinkedList的第一个元素. 1 语法 public E poll() 2 参 ...
- E-R方法进行数据库概念设计
0.试述采用E-R方法进行数据库概念设计的过程. 答:采用E-R方法进行数据库概念设计,可以分成3步进行:首先设计局部E-R模式,然后把各局部E-R模式综合成一个全局的E-R模式,最后对全局E-R模式 ...
- oracle hash join outer,CSS_浅谈Oracle中的三种Join方法,基本概念
Nested loop join:
Outer - phpStudy...
浅谈Oracle中的三种Join方法 基本概念 Nested loop join: Outer table中的每一行与inner table中的相应记录join,类似一个嵌套的循环. Sort mer ...
- 设计模式---3(工厂方法模式的概念,工厂方法模式的实现,工厂方法模式和简单工厂模式比较)
工厂方法模式 概念 工厂方法模式同样属于类的创建型模式又被称为多态工厂模式 . 工厂方法模式的意义 定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不再负责产品的创建,这样核 ...
- java定义一个eat方法_Java继承概念详细解读
继承与合成基本概念 继承:可以基于已经存在的类构造一个新类.继承已经存在的类就可以复用这些类的方法和域.在此基础上,可以添加新的方法和域,从而扩充了类的功能. 合成:在新类里创建原有的对象称为合成.这 ...
最新文章
- php theme_path,PHP_Yii2主题(Theme)用法详解,本文实例讲述了Yii2主题(Theme) - phpStudy
- Java 3.基本数据类型
- Jquery的一些方法
- 8.2 Query 语句优化基本思路和原则
- 微信WeixinJSBridge API 屏蔽右上角分享等常用方法
- 27. PHP 文件创建/写入
- 网吧计费管理系统(武汉理工大学大一下实验(C语言版源码))
- scrollbars属性,MultiLine 属性
- windows2008server实现端口映射代理
- 聊聊CentOS停止维护,要我说这是件大好事!
- Python-数据库
- ansys显示没有提供服务器,ansys 15.0安装在服务器上,运行时出现问题,求大神帮助! - 第 2 页 - 仿真模拟 - 小木虫 - 学术 科研 互动社区...
- 周报(关于项目开发模式的一点总结)
- Python主要用来做什么 它的应用大全有哪些
- C#,索尼偏光相机(Polarization Camera)传感器IMX250和专用SDK简介
- 持续引领产业发展,华为云桌面连续6年位居国内市占率第一
- elasticsearch算法之推荐系统的相似度算法(一)
- [转]电影《不可征服》里的一首诗
- go-elasticSearch实战篇,带你学会elasticSearch的增删改查
- 芯讯通/SIMCOM LTE 模组接入 ThingsCloud