epoll 基本知识与使用
https://blog.csdn.net/qq_35721743/article/details/86742508
epoll 最大的好处在于它不会随着监听 fd 数目的增长而降低效率。
epoll 的接口,一共有三个函数, 都在头文件 #include <sys/epoll.h> 里。
1. 创建 epoll 句柄
int epfd = epoll_create(intsize);
创建一个 epoll 句柄,size 用来告诉内核这个监听的数目一共有多大。当创建好epoll句柄后,它就是会占用一个fd值,在linux下如果查看 /proc/进程id/fd/, 是能够看到这个fd的,所以在使用完epoll后,必须调用 close() 关闭。 否则可能导致 fd 被耗尽。
函数声明: int epoll_create(int size)
该函数生成一个epoll专用的文件描述符。它其实是在内核申请一空间,用来存放你想关注的socket fd 上是否发生以及发生了什么事件。size就是你在这个epoll fd上能关注的最大socket fd 数, 由用户确定, 只要内存空间够用。
2. 将被监听的描述符添加到epoll句柄或从epoll句柄中删除或者对监听事件进行修改
函数声明:int epoll_ctl( int epfd, int op, int fd, struct epoll_event* event )
返回值:如果调用成功返回0,不成功返回-1.
该函数用于控制某个 epoll 文件描述符上的事件,可以注册事件、修改事件、删除事件。
参数:
epfd : 由 epoll_create 生成的 epoll 专用的文件描述符;
op : 要进行的操作,例如注册事件。可能的取值有:
EPOLL_CTL_ADD : 注册新的 fd 到 epfd 中
EPOLL_CTL_MOD : 修改已经注册的 fd 的监听事件
EPOLL_CTL_DEL : 从 epfd 中删除一个 fd
fd : 关联的文件描述符,需要监听的 fd .
event : 指向 epoll_event 的指针, 告诉内核需要监听什么事件 , struct epoll event 结构如下:
struct epoll_event{
__uint32_t events; // Epoll events: EPOLLIN,EPOLLOUT,EPOLLPRI,EPOLLERR,EPOLLHUP,EPOLLET,EPOLLONESHOT
epoll_data_t data; // User data variable
};
typedef union epoll_data{
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;
events 可以是一下几个宏的集合:
EPOLLIN : 触发该事件,表示对应的文件描述符上有可读数据。 (包括对端 SOCKET 正常关闭)
EPOLLOUT : 触发该事件,表示对应的文件描述符上可以写数据;
EPOLLPRI : 表示对应的文件描述符上有紧急的数据可读(这里应该表示有带外数据到来);
EPOLLERR : 表示对应的文件描述符发生错误;
EPOLLHUP : 表示对应的文件描述符被挂断;
EPOLLET : 将 EPOLL 设为 边缘触发 (Edge Triggered) 模式,这是相对于水平触发(Level Triggered)来说的。
EPOLLONESHOT : 只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里。
如:
struct epoll_event ev;
ev.data.fd = listenfd; // 设置与要处理的事件相关的文件描述符
ev.events = EPOLLIN | EPOLLOUT; // 设置要处理的事件类型
epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev); // 注册 epoll 事件
3. 等待事件触发, 当超过 timeout 还没有事件触发时,就超时
int epoll_wait( int epfd, struct epoll_event * events, int maxevents, int timeout );
返回:该函数返回需要处理的事件数目,返回的事件集合在events数组中,数组中实际存放的成员个数是函数的返回值。如返回0表示已超时。
参数:
epfd : 由 epoll_create 生成的epoll专用的文件描述符;
events : 用于回传待处理的事件的数组,从内核得到事件的集合
maxevents : 每次能处理的事件数, 告知内核这个events有多大(数组成员的个数),这个maxevents 的值不能大于创建epoll_create()时候的size。
timeout : 等待 IO 事件发生的超时值; -1相当于阻塞, 0相当于非阻塞
epoll_wait 运行的原理是: 等待注册在 epfd 上的 socket fd 的 事件发生,如果发生,则将发生的fd 和事件保存在 events里,并将epfd上该fd的事件清空。如果需要继续监听该fd,则需要使用EPOLL_CTL_MOD 添加需要监听的事件。因为没有清空epfd上的fd,所以不需要使用EPOLL_CTL_ADD.
最后,水平触发(LT)是默认的工作模式,适合与阻塞和非阻塞socket, 错误率小。边缘出发(ET)是高速工作模式,只适用于非阻塞socket。
epoll 基本知识与使用的更多相关文章
- select poll epoll相关知识速记
缘起 面试的时候经常被问的一个很蛋疼的问题,经常被问,但是知识很零散,难记忆,看完就忘 select 作用 可以监视文件描述符是否可以读写,要求监视的文件描述符是非阻塞的 诞生背景 产生与上个世纪80 ...
- Linux Epoll相关知识
其实在Linux下设计并发网络程序,向来不缺少方法,比如典型的Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,以及 ...
- I/O复用及epoll基础知识
IO multiplexing IO multiplexing这个词可能有点陌生,但是如果我说select,epoll,大概就都能明白了.有些地方也称这种IO方式为event driven IO.我们 ...
- Liunx下Tomcat+MYSQL+Nginx配置
环境:centos6.4 min #安装编译库及依赖模块 yum -y install gcc gcc-c++ autoconf automake make yum -y install zlib z ...
- 《深入理解Android 卷III》第二章 深入理解Java Binder和MessageQueue
<深入理解Android 卷III>即将公布.作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白,即Android Framework中和UI相关的部分. ...
- Python菜鸟之路:Python基础-Socket编程-2
在上节socket编程中,我们介绍了一些TCP/IP方面的必备知识,以及如何通过Python实现一个简单的socket服务端和客户端,并用它来解决“粘包”的问题.本章介绍网络编程中的几个概念:多线程. ...
- epoll 知识总结
poll/select/epoll 对比 http://www.cnblogs.com/apprentice89/p/3234677.html ---有待继续学习 http://blog.chi ...
- Python框架之Tornado(二)预备知识epoll最好的讲解
问:epoll 或者 kqueue 的原理是什么?为什么 epoll 和 kqueue 可以用基于事件的方式,单线程的实现并发?我没看过 linux 内核,对这方面一直有疑问…… 必须从很多基础的概念 ...
- Android系统--输入系统(一)必备的Linux知识_inotify和epoll
Android系统--输入系统(一)必备的Linux知识_inotify和epoll 引入 1. 笔记本电脑插入外接键盘,两个键盘都可以使用 a. 键盘即插即用--如何检测键盘的接入和拔出 hotpl ...
- 知识联结梳理 : I/O多路复用、EPOLL(SELECT/POLL)、NIO、Event-driven、Reactor模式
为了形成一个完整清晰的认识,将概念和关系梳理出来,把坑填平. I/O多路复用 I/O多路复用主要解决传统I/O单线程阻塞的问题.它通过单线程管理多个FD,当监听的FD有状态变化的时候的,调用回调函数, ...
随机推荐
- 解决 VSCode git commit 时 No such file or directory 报错问题
在git 进行 commit 时出现了 Git: .git/hooks/pre-commit: line 2: ./node_modules/pre-commit/hook: No such file ...
- 《在编译两个不同的库时,不想相互include头文件,但又需要用到对方的函数,可以用extern》
以下是个人理解,水平有限,可能不太准确.有问题,麻烦指出. demo: a.so void a_fun(void) { b_fun(); } b.so void b_fun(void) { //略 } ...
- syntax_lead_x.txt
select lead( t1.field_date-1, 1, null ) over(partition by t1.field_str order by t1.field_str),*from ...
- 【文献阅读】Automatic berthing for an underactuated unmanned surface vehicle: A real-time motion planning approach
(1)文章工作 This paper presents Extended Dynamic Window Approach (EDWA) for the automatic berthing of an ...
- C++内存泄漏——原因、避免以及定位
https://bbs.huaweicloud.com/blogs/351858
- JSONObject和JSONArray的区别
JSONObject是用{}表示: JSONArray是用[]表示,相当于[{ }, { }],是由JSONObject的集合. 定义一个String类型 JSONObject jsonOject = ...
- docker 部署的mariadb数据库备份还原方案
docker部署下的mariadb数据库备份还原方案 背景:在使用docker部署的mariadb时,我们会将容器内的数据卷挂载到宿主机上,做简单的备份,容器在正常运行和停止的情况下,能快速创建mar ...
- 一些test短代码
#include <stdio.h> int main(){ char ray_tx_pwr[2][3]={{1,2,3},{4,5,6}}; int i = 0; printf(&quo ...
- c语言学习--静态函数
静态函数 #include<stdio.h> //这是静态函数, 静态函数只能在当前文件调用,其他文件下面的函数是没法调用到这个函数的 static void fun1() { print ...
- cc1
基础 cc接口及类介绍 Transformer接口 Defines a functor interface implemented by classes that transform one obje ...