前言

  之前已经介绍过select函数,请参考这篇博客:https://www.cnblogs.com/liudw-0215/p/9661583.html,原理都是类似的,有时间先阅读下那篇博客,以便于理解这篇博客。

  一、poll函数

  1、函数说明

  原型:int poll(struct pollfd *fds, nfds_t nfds, int timeout);
  参数说明: 

  参数fds:

  struct pollfd {

int fd; /* 文件描述符 */

short events; /* 监控的事件 */

short revents; /* 监控事件中满足条件返回的事件 */

};

POLLIN 普通或带外优先数据可读,即POLLRDNORM | POLLRDBAND

POLLRDNORM 数据可读

POLLRDBAND 优先级带数据可读

POLLPRI 高优先级可读数据

POLLOUT 普通或带外数据可写

POLLWRNORM 数据可写

POLLWRBAND 优先级带数据可写

POLLERR 发生错误

POLLHUP 发生挂起

POLLNVAL 描述字不是一个打开的文件

nfds:监控数组中有多少文件描述符需要被监控

timeout:毫秒级等待

-1:阻塞等,#define INFTIM -1 Linux中没有定义此宏

0:立即返回,不阻塞进程

>0:等待指定毫秒数,如当前系统时间精度不够毫秒,向上取值

  如果不再监控某个文件描述符时,可以把pollfd中,fd设置为-1,poll不再监控此pollfd,下次返回时,把revents设置为0。

  2、程序示例

  理解select之后,再解poll就很简单了,服务端代码如下:

  


  程序中封装了包裹函数,有需要的请评论留言。

  二、epoll函数

  1、介绍 

  epoll是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率,因为它会复用文件描述符集合来传递结果而不用迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合,另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。

  目前epell是linux大规模并发网络程序中的热门首选模型。

  epoll除了提供select/poll那种IO事件的电平触发(Level Triggered)外,还提供了边沿触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。

  2、函数说明

  跟select和poll不一样,epoll不是一个函数,需要三个函数一起来实现,分别为epoll_create、epoll_ctl和epoll_wait,下面分别来说明这三个函数。

  (1)epoll_create函数

  功能:创建一个epoll,参数size用来告诉内核监听的文件描述符的个数,跟内存大小有关。

  原型:int epoll_create(int size)

  又到了上图时间了,如下图:  PS:依旧是全博客园最丑图,不接受反驳。

  

  epoll_create返回的epfd,其实创建了红黑树,是它的根节点。

  (2)epoll_ctl函数

  功能:控制某个epoll监控的文件描述符上的事件:注册、修改、删除。

  原型:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)

  参数说明: 

epfd: 为epoll_creat的

op: 表示动作,用3个宏来表示:

EPOLL_CTL_ADD (注册新的fd到epfd),

EPOLL_CTL_MOD (修改已经注册的fd的监听事件),

EPOLL_CTL_DEL (从epfd删除一个fd);

event: 告诉内核需要监听的事件

struct epoll_event {

__uint32_t events; /* Epoll events */

epoll_data_t data; /* User data variable */

};

typedef union epoll_data {

void *ptr;

int fd;

uint32_t u32;

uint64_t u64;

} epoll_data_t;

EPOLLIN : 表示对应的文件描述符可以读(包括对端SOCKET正常关闭)

EPOLLOUT: 表示对应的文件描述符可以写

EPOLLPRI: 表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来)

EPOLLERR: 表示对应的文件描述符发生错误

EPOLLHUP: 表示对应的文件描述符被挂断;

EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)而言的

EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里

  (3)epoll_wait函数

  功能:等待所监控文件描述符上有事件的产生

  原型:int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)

  参数说明:  

events: 用来存内核得到事件的集合,

maxevents: 告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create()时的size,

timeout: 是超时时间

-1: 阻塞

0: 立即返回,非阻塞

>0: 指定毫秒

返回值: 成功返回有多少文件描述符就绪,时间到时返回0,出错返回-1

  3、示例程序

  服务端程序如下:

  

  

  总结:需要包裹函数、客户端等程序的,欢迎留言

详解网络编程必会的poll和epoll函数的更多相关文章

  1. Oracle Statspack报告中各项指标含义详解~~学习性能必看!!!

    Oracle Statspack报告中各项指标含义详解~~学习性能必看!!! Data Buffer Hit Ratio#<#90# 数据块在数据缓冲区中的命中率,通常应该在90%以上,否则考虑 ...

  2. [转]Hadoop集群_WordCount运行详解--MapReduce编程模型

    Hadoop集群_WordCount运行详解--MapReduce编程模型 下面这篇文章写得非常好,有利于初学mapreduce的入门 http://www.nosqldb.cn/1369099810 ...

  3. [转载]详解网络传输中的三张表,MAC地址表、ARP缓存表以及路由表

    [转载]详解网络传输中的三张表,MAC地址表.ARP缓存表以及路由表 虽然学过了计算机网络,但是这部分还是有点乱.正好在网上看到了一篇文章,讲的很透彻,转载过来康康. 本文出自 "邓奇的Bl ...

  4. 详解Python编程中基本的数学计算使用

    详解Python编程中基本的数学计算使用 在Python中,对数的规定比较简单,基本在小学数学水平即可理解. 那么,做为零基础学习这,也就从计算小学数学题目开始吧.因为从这里开始,数学的基础知识列位肯 ...

  5. 《Unix 网络编程》14:高级 I/O 函数

    高级 I/O 函数 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ...

  6. PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明

    PHP函数篇详解十进制.二进制.八进制和十六进制转换函数说明 作者: 字体:[增加 减小] 类型:转载   中文字符编码研究系列第一期,PHP函数篇详解十进制.二进制.八进制和十六进制互相转换函数说明 ...

  7. Linux网络编程必看书籍推荐

    首先要说讲述计算机网络和TCP/IP的书很多. 先要学习网络知识才谈得上编程 讲述计算机网络的最经典的当属Andrew S.Tanenbaum的<计算机网络>第五版,这本书难易适中. &l ...

  8. POSIX 线程详解(经典必看)

    http://www.cnblogs.com/sunminmin/p/4479952.html 总共三部分: 第一部分:POSIX 线程详解                               ...

  9. (转载)详解网络传输中的三张表,MAC地址表、ARP缓存表以及路由表

    郑重声明:原文转载于http://dengqi.blog.51cto.com/5685776/1223132 向好文章致敬!!! 一:MAC地址表详解 说到MAC地址表,就不得不说一下交换机的工作原理 ...

随机推荐

  1. 给div"上"滑动条

    最近做项目时修改一个遗留的bug,大概是这样:有一个聊天窗口,用户聊天内容展现在窗口上.其实这个窗口是一个带滑动条的div,随着聊天内容的添加,滑动条也越来越长了,这不是重点,重点是每次刷新窗口时候, ...

  2. Turtle库的建立——汉诺塔

    Turtle库的建立——汉诺塔 1.首先是要用递归方法来完成这个汉诺塔法则 2.其次,就要编程好代码以及熟练掌握Turtle函数库 一.  相关代码如下: import turtle class St ...

  3. 《Linux就该这么学》第十六天课程

    今天笔记有点少就不发了,分享一下第23章 使用OpenLDAP部署目录服务很实用 下面是DHCP动态管理地址,如需深入学习请前往 https://www.linuxprobe.com/chapter- ...

  4. UE4动画及相关物理的更新顺序图

  5. 用clock()函数计时的坑

    程序中经常用time()函数来返回当前系统时间的秒数,来计时或计算时间差.如果需要用到更高精度的时间,就会自然想到用clock()函数.想当然的认为它返回从程序开始tick数,用clock()/CLO ...

  6. poj1164 The Castle

    有一个n*m的城堡,由一个个小房间组成,每个房间由一个零和四面的墙组成,每个房间都有一个价值, 价值的计算方式是:west_walls价值为1,north_walls价值为2,east_walls价值 ...

  7. MyBatis逆向工程自动生成代码

    MyBatis逆向工程根据数据库表自动生成mapper.xml,entity类,mapper类,简直不要 太方便好嘛 下面贴上关键配置代码,以免以后找不到 generator.xml <?xml ...

  8. lambada

    一.动态创建 ParameterExpression parameter = Expression.Parameter(typeof(User), "u"); //创建委托 Mem ...

  9. qrcode.php

    <!doctype html><html><head> <meta charset="UTF-8"/> <meta name= ...

  10. Linux下Oracle表空间及用户创建

    记录详细过程以备使用 Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 Connected as sys@i ...