epoll 中EPOLLIN 和 EPOLLOUT

epoll主要是事件回调运行的,我们使用socket的时候主要使用两个事件

EPOLLOUT事件:
EPOLLOUT事件只有在连接时触发一次,表示可写,其他时候想要触发,那你要先准备好下面条件:
1.某次write,写满了发送缓冲区,返回错误码为EAGAIN。
2.对端读取了一些数据,又重新可写了,此时会触发EPOLLOUT。
简单地说:EPOLLOUT事件只有在不可写到可写的转变时刻,才会触发一次,所以叫边缘触发,这叫法没错的!

其实,如果你真的想强制触发一次,也是有办法的,直接调用epoll_ctl重新设置一下event就可以了,event跟原来的设置一模一样都行(但必须包含EPOLLOUT),关键是重新设置,就会马上触发一次EPOLLOUT事件。

从应用上看这个事件是本地端状态改变了。

EPOLLIN事件:
EPOLLIN事件则只有当对端有数据写入时才会触发,所以触发一次后需要不断读取所有数据直到读完EAGAIN为止。否则剩下的数据只有在下次对端有写入时才能一起取出来了。
现在明白为什么说epoll必须要求异步socket了吧?如果同步socket,而且要求读完所有数据,那么最终就会在堵死在阻塞里。

从应用上看这个事件就是用来读取数据的。

时间: 2024-11-11 23:13:11

epoll 中EPOLLIN 和 EPOLLOUT的相关文章

epoll中et+多线程模式中很重要的EPOLL_ONESHOT实验

因为et模式需要循环读取,但是在读取过程中,如果有新的事件到达,很可能触发了其他线程来处理这个socket,那就乱了. EPOLL_ONESHOT就是用来避免这种情况.注意在一个线程处理完一个socket的数据,也就是触发EAGAIN errno时候,就应该重置EPOLL_ONESHOT的flag,这时候,新到的事件,就可以重新进入触发流程了. 服务器代码如下: #include <stdio.h> #include <stdlib.h> #include <unistd.h

AF_UNIX和AF_INET域的socket在epoll中的差异

1.AF_UNIX & SOCK_STREAM 1.1 accept_socket BLOCK EPOLLIN|EPOLLET 1.2 accept_socket NON-BLOCK EPOLLIN|EPOLLET 1.3 accept_socket BLOCK EPOLLIN 1.4 accept_socket NON-BLOCK EPOLLIN  2.AF_INET & SOCK_STREAM 2.1 accept_socket NON-BLOCK EPOLLIN 2.2 accept

linux IO复用(epoll)小记

一.epoll简介 epoll是Linux内核为处理大批量文件描述符而作了改进的poll, 是Linux下多路复用IO接口select/poll的增强版本, 它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率.另一点原因就是获取事件的时候, 它无须遍历整个被侦听的描述符集, 只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了. 二.epoll的API函数 1. 句柄创建函数 int epoll_create(int size); 创建一个epoll的句柄

UDT中的epoll

epoll 是为处理大量句柄而改进的poll,在UDT中也有支持.UDT使用了内核提供的epoll,主要是epoll_create,epoll_wait,epoll_ctl,UDT定义了CEPollDesc这个结构来管理epoll的描述符和套接字. struct CEPollDesc { int m_iID;                                // epoll ID std::set<UDTSOCKET> m_sUDTSocksOut;       // set o

Python——在Python中如何使用Linux的epoll

在Python中如何使用Linux的epoll 目录 序言 阻塞socket编程示例 异步socket的好处以及Linux epoll 带epoll的异步socket编程示例 性能注意事项 源代码 序言 从2.6开始,Python包含了访问Linux epoll库的API.这篇文章用几个简单的python 3例子来展示下这个API.欢迎大家质疑和反馈. 阻塞socket编程示例 示例1用python3.0搭建了一个简单的服务:在8080端口监听HTTP请求,把它打印到控制台,并返回一个HTTP响

Linux内核中网络数据包的接收-第二部分 select/poll/epoll

和前面文章的第一部分一样,这些文字是为了帮别人或者自己理清思路的,而不是所谓的源码分析,想分析源码的,还是直接debug源码最好,看任何文档以及书都是下策.因此这类帮人理清思路的文章尽可能的记成流水的方式,尽可能的简单明了. Linux 2.6+内核的wakeup callback机制 Linux 内核通过睡眠队列来组织所有等待某个事件的task,而wakeup机制则可以异步唤醒整个睡眠队列上的task,每一个睡眠队列上的节点都拥有一个 callback,wakeup逻辑在唤醒睡眠队列时,会遍历

使用epoll编写TCP服务器端

epoll:结合了select与poll的优点,以及优化了它们的不足,来实现同时控制多个句柄,以此来实现多路复用.它也是使用文件系统的相关信息来实现的 它所使用的三个系统调用函数 1.epoll_create函数 创建一个句柄,size大小可不关心,该句柄会占用一个文件描述符位置 2.epoll_ctl函数,它需要使用一个结构体告诉内核需监听什么事件 它为一个事件注册函数,先将要监听的何种事件进行注册,不同于select函数,它是在监听的时候就要告诉是何种事件 op指要对某个描述符进行何种操作(

基于epoll的聊天室程序

epoll相对于poll和select这两个多路复用的I/O模型更加的高效.epoll的函数很简单,麻烦的地方在于水平触发和边沿触发. 用张图来说明下 ET(边沿)只是在状态反转时触发,比如从不可读到可读.而LT(水平)就是如果可读,就会一直触发.所以在使用ET的时候要做一些额外的处理,比如可读的,一直把缓冲区读完,进入不可读状态,下次来数据才会触发. 下面贴出代码,只是一个简单的练习的例子socketheads.h C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

IO多路复用--epoll详解

epoll 或者 kqueue 的原理是什么? [转自知乎] Epoll 引入简介 首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行I/O操作的内核对象. 不管是文件,还是套接字,还是管道,我们都可以把他们看作流.之后我们来讨论I/O的操作,通过read,我们可以从流中读入数据:通过write,我们可以往流写入数据.现在假定一个情形,我们需要从流中读数据,但是流中还没有数据,(典型的例子为,客户端要从socket读如数据,但是服务器还没有把数据传回来),这时候该怎么办