Linux网络模型epoll

epoll
是一种I/O事件通知机制,是linux 内核实现IO多路复用的一个实现。
IO多路复用是指在一个操作里同时监听多个输入输出源,在其中一个或多个输入输出源
可用的时候返回,然后对其进行读写操作I
epoll的核心是3个API,核心数据结构是: 1个红黑树和1个链表

  • epoll_create 创建epollevent对象红黑树双向链表队列
  • epoll_ctl 注册事件把感兴趣的事件添加到红黑树里面
  • epoll_wait 获得可用事件的通知-在工作线程里面

epoll_create
int epollfd = epoll_create(fdsize)
调用epoll create方法时, 内核会创建一个eventpoll对象

  • 等待队列用于保存当前阻塞的线程用于可读可写时唤醒队列中的线程
  • 红黑树用于保存监视的socket事件
  • 就绪队列双向链表用于保存可读可写就绪事件的socket

epoll ctl
struct epoll event ev;
ev.events= EPOLLIN| EPOLLET:
ev.data.fd = sockfd;
epoll ct(epollfd, EPOLL CTL DEL, sockfd, &ev); //成功返回o,不成功返回-1。
功能:将需监听的fd添加到epolfd对应的红黑树上
(1) epollfd: epoll create 的返回值
(2)对sockfd的操作类型:是删除还是增加。EPOLL CTL ADD、EPOLL CTL MOD、
EPOLL CTL DEL
(3) sockfd需要操作的文件fd
(4)监听sockfd的哪些事件:读事件还是写事件。监听事件的方式:是水平触发还是边沿触发。

  • EPOLLIN :表示监听对应文件描述符,读事件(包括对端SOCKET正常关闭) ;
  • EPOLLOUT:表示监听对应文件描述符, 写事件:
  • EPOLLPRI:表 示监听对应文件描述符,紧急数据可读事件(这里应该表示有带外数据到来) ;
  • EPOLLERR:表示监听文件描述符,发生错误事件:
  • EPOLLHUP:表示监听 文件描述符,被挂断事件;
  • EPOLLLT:将epoll设为水平触发模式
  • EPOLLET:将epoll设 为边沿触发模式,该参数缺省状态为水平触发LT
  • EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socketfd
    的话

epoll的两种触发模式
epol的水平触发和边沿触发:
(1)水平触发LT:只要这个文件描述符还有数据可读或可写,每次epoll wait都会返回它的事件,
提醒用户程序去操作; |
(2)边沿触发ET:在它检测到有I/O事件时,通过epoll wait调用会得到有事件通知的文件描述符
a、可读EPOLLOIN事件, 则必须将该文件描述符一直读到空,让errno返回EAGAIN为止,否则
下次的epoll wait 不会返回余下的数据,会丢掉事件。
b、可写EPOLLOUT事件只有在连接时触发一 次,表示可写,其他时候想要触发
//1.某次write,写满了发送缓冲区,返回错误码为EAGAIN.
//2.对端读取了一些数据,又重新可写了,此时会触发EPOLLOUT.
强制触发,调用epoll ctl(epfd.EPOLL CTL MOD.fdev)重新设置.下event

在这里插入图片描述
epoll wait
int num = epoll wait(epoll->epollfd, events, EPOLLEVENTS,-1);
功能:发现并获得”就绪“状态的fd.
返回值:成功,返回就绪文件描述符个数。失败返回-1,并设置errno
(1) epfd: epoll create创建的epollfd.
(2) events:个 数组, 若检测到某fd处于就绪状态, 将事件从内 核事件表复制到该数组。
(3) maxevents:指定最多监听多少事件。
(4) timeout: epll超时时间,单位毫秒。
为-1表示阻塞,为o表示非阻塞,其他值表示超时时间。

猜你喜欢

转载自blog.csdn.net/qq_48322523/article/details/120353244