一、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方法的基本概念相关推荐

  1. java poll()是什么方法,JAVA学习中的一点小发现:LinkedList中.poll()方法在输出时使用应注意的小点...

    在学习JAVA类集一章中关于LinkedList子类中.poll()方法易错点的分析心得 例如如下代码: package Test; import java.util.LinkedList; publ ...

  2. Linux一个驱动管理多个设备,poll方法(select多路监控原理与实现)

    1.什么是Poll方法,功能是什么? 2.Select系统调用(功能) Select系统调用用于多路监控,当没有一个文件满足要求时,select将阻塞调用进程. int select(int maxf ...

  3. Queue接口分析:add和offer区别,remove和poll方法到底啥区别

    往队列中添加元素有两个方法,分布是add和offer方法,两者的入参和返回值都一样,或许很多同学都奇怪,为什么,要有这两个功能类似(都是添加元素),但方法名不一样的方法,看看源码的注释 以下为Queu ...

  4. java的poll方法_Java中的队列poll()方法示例

    使用poll()方法获取并删除Queue中的第一个元素. 创建一个队列-Queue q = new LinkedList(); 添加一些元素-q.add("abc"); q.add ...

  5. java linkedlist poll_Java LinkedList poll()方法

    Java LinkedList poll()方法 java.util.LinkedList.poll() 检索并删除LinkedList的第一个元素. 1 语法 public E poll() 2 参 ...

  6. E-R方法进行数据库概念设计

    0.试述采用E-R方法进行数据库概念设计的过程. 答:采用E-R方法进行数据库概念设计,可以分成3步进行:首先设计局部E-R模式,然后把各局部E-R模式综合成一个全局的E-R模式,最后对全局E-R模式 ...

  7. oracle hash join outer,CSS_浅谈Oracle中的三种Join方法,基本概念 Nested loop join: Outer - phpStudy...

    浅谈Oracle中的三种Join方法 基本概念 Nested loop join: Outer table中的每一行与inner table中的相应记录join,类似一个嵌套的循环. Sort mer ...

  8. 设计模式---3(工厂方法模式的概念,工厂方法模式的实现,工厂方法模式和简单工厂模式比较)

    工厂方法模式 概念 工厂方法模式同样属于类的创建型模式又被称为多态工厂模式 . 工厂方法模式的意义 定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不再负责产品的创建,这样核 ...

  9. java定义一个eat方法_Java继承概念详细解读

    继承与合成基本概念 继承:可以基于已经存在的类构造一个新类.继承已经存在的类就可以复用这些类的方法和域.在此基础上,可以添加新的方法和域,从而扩充了类的功能. 合成:在新类里创建原有的对象称为合成.这 ...

最新文章

  1. php theme_path,PHP_Yii2主题(Theme)用法详解,本文实例讲述了Yii2主题(Theme) - phpStudy
  2. Java 3.基本数据类型
  3. Jquery的一些方法
  4. 8.2 Query 语句优化基本思路和原则
  5. 微信WeixinJSBridge API 屏蔽右上角分享等常用方法
  6. 27. PHP 文件创建/写入
  7. 网吧计费管理系统(武汉理工大学大一下实验(C语言版源码))
  8. scrollbars属性,MultiLine 属性
  9. windows2008server实现端口映射代理
  10. 聊聊CentOS停止维护,要我说这是件大好事!
  11. Python-数据库
  12. ansys显示没有提供服务器,ansys 15.0安装在服务器上,运行时出现问题,求大神帮助! - 第 2 页 - 仿真模拟 - 小木虫 - 学术 科研 互动社区...
  13. 周报(关于项目开发模式的一点总结)
  14. Python主要用来做什么 它的应用大全有哪些
  15. C#,索尼偏光相机(Polarization Camera)传感器IMX250和专用SDK简介
  16. 持续引领产业发展,华为云桌面连续6年位居国内市占率第一
  17. elasticsearch算法之推荐系统的相似度算法(一)
  18. [转]电影《不可征服》里的一首诗
  19. go-elasticSearch实战篇,带你学会elasticSearch的增删改查
  20. 芯讯通/SIMCOM LTE 模组接入 ThingsCloud

热门文章

  1. 【毕业季】即将踏入大二的我有话要说
  2. Perl数组和hash相关函数
  3. C++——sort函数
  4. DHCP服务器配置 ,详细实验教程!
  5. 中国开发者现状调查报告:30至40岁程序员比例上升,近六成从业者不反对“大小周”
  6. [转载]总结LDO与升压芯片的选型
  7. 什么是铠装电缆,什么是非铠装电缆,两者的区别?
  8. 做什么类型的网站容易挂google广告容易取得长久收入
  9. Eclipse项目没错却有红叉解决方法
  10. 【全套完结】蓝桥杯单片机--- 从省赛到国赛