epoll水平触发与边缘触发

把高电平看作文件描述符是可读或可写状态,低电平黑色表示不可读或不可写,epoll_wait的水平触发就是蓝色的时候epoll_wait就会被触发,而边缘触发就是红色的时候epoll_wait会触发,且只会触发一次。比如,client_fd在某时刻充入数据,epoll_wait第一次检测到,水平、边缘都会触发,进程开始读数据,若数据没有读完。那么水平触发会在下一次运行到epoll_wait的时候再触发一次,而边缘触发就不会。
水平触发下,可能会多次调用epoll_wait导致效率低下。而边缘触发下,如果第一次触发没有读干净缓冲区,那么就只能等到下一次冲入数据才能触发epoll_wait读出上一次的数据,所以在边缘触发下,必须一次将缓冲区的数据读干净。
方法就是设置epoll_event的events设置为 EPOLLET ,在死循环里一直读client_fd,但读完后read系统调用会阻塞,所以要将client_fd设置为非阻塞:
int flags = fcntl(client_fd, F_GETFL);//获取的cfd的标志位
flags |= O_NONBLOCK;
fcntl(client_fd,F_SETFL,flags);
struct epoll_event e;
e.events = EPOLLIN | EPOLLET;
...
当read读非阻塞文件描述符读干净的时候,不会阻塞,而是返回-1并且把errno设置为EAGAIN,这时就可以跳出死循环。
while (1)
{
char buf[SIZE] = "";
int n = read(fd, buf, SIZE);
if (n < 0)
{
if (errno == EAGAIN)
{
printf("读完了\n");
break;
}
Close(fd);
epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
perror("read");
return 1;
}
else if (0 == n) // 套接字关闭
{
printf("client close\n");
Close(fd);
epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
break;
}
else
{
Write(STDOUT_FILENO, buf, SIZE);
Write(fd, buf, n);
}
}
epoll水平触发与边缘触发的更多相关文章
- 实例浅析epoll的水平触发和边缘触发,以及边缘触发为什么要使用非阻塞IO
一.基本概念 我们通俗一点讲: Level_triggered(水平触发):当被监控的 ...
- epoll的水平触发和边缘触发,以及边缘触发为什么要使用非阻塞IO
转自:http://www.cnblogs.com/yuuyuu/p/5103744.html 一.基本概念 ...
- 条件触发和边缘触发 及 epoll 的长处
条件触发: 仅仅要输入缓冲有数据就会一直通知该事件 边缘触发: 输入缓冲收到数据时仅注冊1次该事件.即使输入缓冲中还留有数据,也不会再进行注冊 水平触发(level-triggered.也被称为条件触 ...
- epoll ET(边缘触发) LT(水平触发)
EPOLL事件有两种模型: Edge Triggered (ET) 边缘触发只有数据到来,才触发,不管缓存区中是否还有数据.Level Triggered (LT) 水平触发只要有数据都会触发. 首先 ...
- Linux网络编程之select、poll、epoll的比较,以及epoll的水平触发(LT)和边缘触发(ET)
Linux的网络通信先后推出了select.poll.epoll三种模式. select有以下三个问题: (1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大. ...
- epoll的边缘触发与水平触发
epoll的边缘触发与水平触发 Tcp连接是双向的,内核为每个socket维护两个缓冲区,读缓冲区与写缓冲区,内核会一个关注这两个缓冲区,当采用水平触发时,对于写缓冲区而言,如果有多余空间可写,对于读 ...
- epoll水平/边缘触发模式下阻塞/非阻塞EPOLLOUT事件触发条件及次数
在IO多路复用技术中,epoll默认的事件触发模式为Level_triggered(水平触发)模式,即当被监控的文件描述符上有可读/写事件发生时,epoll_wait()会通知处理程序去读写.如果这次 ...
- 边缘触发(Edge Trigger)和条件触发(Level Trigger)
int select(int n, fd_set *rd_fds, fd_set *wr_fds, fd_set *ex_fds, struct timeval *timeout); sele ...
- jenkins 判断是手动触发还是定时器触发
根据变量BUILD_CAUSE的值可以判断本次触发是手动触发还是定时器触发 手动触发:MANUALTRIGGER 定时器触发:TIMERTRIGGER
- Unity插件之NGUI学习(6)—— 关于Widget怎样加入触发事件(触发OnClick)
NGUI中,Button本身就带有OnClick事件,可是Sprite,Label等( 也绑有Widget的)并没有触发事件,事实上NGUI的事件触发都必须加入Box Collider,并勾选Is T ...
随机推荐
- U390630 分考场题解
题目链接:U390630 分考场 本题来自于2019年蓝桥杯国赛的题.在洛谷上也被标为了假题.原因是首先官方在需要输出浮点数的情况下,并没有开启spj,并且官方所给的数据当中,总有一两个数据以不知道到 ...
- 201871010111-刘佳华 实验二 个人项目—《D[01]背包问题》项目报告
实验二 软件工程个人项目 ========== 时间:2021-3-18 项目 内容 课程班级博客链接 课程链接 这个作业要求链接 作业要求 我的课程学习目标 1.了解软件工程过程中个人项目的开发流程 ...
- docker 安装的jenkins如何执行宿主机的shell启动jar包
最近在用docker做自动化部署的时候遇到一个问题,就是用docker装的jenkins可以通过映射执行宿主机脚本.但是,却无法通过shell脚本启动宿主机jar包.经排查最终用以下方案完美解决. 一 ...
- uni-uadmin后台管理系统|uniapp+uView跨端后台框架实例
基于uniapp+uview+uni-ui跨平台手机端后台管理系统UniappUAdmin. uniapp-uadmin 基于uni-app+uView+uniUI研发的跨端手机后台管理系统项目.全新 ...
- Flink-启动后无法访问WebUI界面(Flink1.16)
问题描述 通过./bin/start-cluster.sh启动Flink程序,正常启动后无法通过浏览器访问web UI界面,http://192.168.80.133:8081. 问题原因 Flink ...
- OGG常用运维命令
1. 管理(MGR)进程命令 INFO MANAGER 返回有关管理器端口和进程id的信息. START MANAGER 开启管理进程 STATUS MANAGER ...
- google recaptcha 谷歌人机身份验证超详细使用教程,前端/后端集成说明
壹 ❀ 引 在日常页面交互中,验证码使用是极为频繁的,登录注册验证,非机器人操作验证等等,它遍布于每一个网站.说到验证码实现,Goole Recaptcha是一个非常不错的选择,那么希望通过本文的使用 ...
- NC208250 牛牛的最美味和最不美味的零食
题目链接 题目 题目描述 牛牛为了减(吃)肥(好),希望对他的零食序列有更深刻的了解,所以他把他的零食排成一列,然后对每一个零食的美味程度都打了分,现在他有可能执行两种操作: eat k:吃掉当前的第 ...
- NC13885 Music Problem
题目链接 题目 题目描述 Listening to the music is relax, but for obsessive(强迫症), it may be unbearable. HH is an ...
- 【Android】使用AIDL实现进程间传递对象案例
1 前言 在 Android--使用AIDL实现进程间通讯简单案例 中介绍了使用 AIDL 在进程间传递字符串,对于8种基本数据类型( byte.short.int.long.float.doub ...