关闭

epoll模型的实现原理

363人阅读 评论(0) 收藏 举报
分类:

一、epoll模型概念与比较

select、poll、epoll一样都是I/O多路复用技术。网络编程还有其他常用模型,如每连接一进程(PPC, 在Apache服务器中采用)、每连接一线程(TPC)。还有Windows中的IOCP

select/pselect, poll/ppoll与epoll的比较:

1. 历史上,select最先出现,pselect是POSIX定义的pselect变体的版本,可以指定信号屏蔽字。select可以侦听的文件描述符数收到FD_SETSIZE,Linux的值为1024

[cpp] view plain copy
  1. #include <sys/select.h>  
  2.   
  3. int pselect(int nfds, fd_set *restrict readfds,  
  4.        fd_set *restrict writefds, fd_set *restrict errorfds,  
  5.        const struct timespec *restrict timeout,  
  6.        const sigset_t *restrict sigmask);  
  7. int select(int nfds, fd_set *restrict readfds,  
  8.        fd_set *restrict writefds, fd_set *restrict errorfds,  
  9.        struct timeval *restrict timeout);  
2. 随后,出现了poll/ppoll,去掉select的FD_SETSIZE的限制,并使用struct pollfd描述感兴趣的事件,粒度更细。

[cpp] view plain copy
  1. #include <poll.h>  
  2.   
  3. int poll(struct pollfd fds[], nfds_t nfds, int timeout);  
  4. int ppoll(struct pollfd *fds, nfds_t nfds,  
  5.          const struct timespec *timeout_ts, const sigset_t *sigmask);  

3. 在后,Linux2.5开始引入了epoll模型,该模型的使用需要一组系统调用,将注册感兴趣的事件(epoll_ctl)与获取时间通知操作(epoll_wait)解耦,解决了每次调用select和poll都需要在内核态和用户态之间来回拷贝文件描述符列表,且在返回后,调用者还需要手动遍历整个列表进行判断所带来的性能问题。

注:尽管epoll号称异步事件通知,但仍需调用者将事件poll out,而非像IOCP那样自动在独立的工作线程中完成用户回调的方式。

[cpp] view plain copy
  1. #include <sys/epoll.h>  
  2. int epoll_create(int size); //只要size>=0即可。内核会忽略掉size的值  
  3. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);  
  4. int epoll_wait(int epfd, struct epoll_event *events,  
  5.              int maxevents, int timeout); // maxevents不可大于#define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event))  

二、epoll的实现

epoll是基于eventpollfs文件系统实现的。

1. epoll_create实际上会在内核中创建一个eventpollfs文件系统的文件和一个struct eventpoll的实例,后者拥有一个描述已注册侦听事件列表(每一项用struct epitem描述,基于红黑树实现)、一个ready列表(维护待通知事件)和一个等待队列(用于对epoll_wait的进程阻塞)。

2. epool_ctl用户注册侦听事件,简单来讲,就是创建一个epitem,加入已注册侦听事件列表(内部使用红黑树组织),同时会为item注册一个回调函数(ep_ptable_queue_proc)到被侦听描述符,描述符上有事件到达(如socket接收缓冲区中到来数据)时会回调本函数。回调函数的主要作用就是将item加入ready列表,并唤醒阻塞在epoll_wait调用上的进程,这样就完成了所谓的“异步事件”通知机制。

3. epoll_wait主要内容为:首先判断ready列表是否有待通知事件,若无,则会阻塞在eventpoll上对应的等待队列。等待通知到达后,会将到达通知对应数据从内核态拷贝到用户态的events数组中。

注:网上有人说从内核态到用户态传递通知是基于共享内存(mmap)的,那应该是较老的内核或2.5版本中的实现,3.10版本并没有使用mmap。

0
0
查看评论

我读过最好的Epoll模型讲解

首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行I/O操作的内核对象。     不管是文件,还是套接字,还是管道,我们都可以把他们看作流。     之后我们来讨论I/O的操作,通过read,我们可...
  • mango_song
  • mango_song
  • 2015-01-12 16:26
  • 14200

Linux网络编程--epoll 模型原理详解以及实例

1.简介Linux I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数。Linux 2.6内核中有提高网络I/O性能的新方法,即epoll 。 epoll是什么?按照man手册的说法是为处理大批量句柄而作了改进的poll。要使用epoll只需要以下的三个系...
  • u010193457
  • u010193457
  • 2015-10-08 16:53
  • 5919

Linux简单高并发模型——Epoll + 线程池

首先是一个locker.h的文件,封装了信号量、互斥量、条件变量。 在线程池中的任务队列需要互斥量的保护,当任务队列中有任务到达时,需要唤醒一个等待pthread_cond_wait()的线程,线程池停止时,需要唤醒所以的线程,调用的是pthread_cond_broadcast()。 ...
  • qq_25425023
  • qq_25425023
  • 2017-04-16 23:19
  • 964

基于 epoll 的网络高并发模型开发

此程序最早是基于网上的一个 select 程序开发的,后来让我改造成 epoll 模型的并发程序,最后又稍作改造并测试,形成现在的程序,最早的程序出处已经忘记了。其中对于 epoll 的 ET 和 LT 模式的使用一开始存在一些误解,这主要是由于一开始参考的网上的一些例子导致的,最终看了一个兄弟的帖...
  • raoping2017
  • raoping2017
  • 2017-03-31 16:39
  • 441

多线程、IO模型、epoll杂谈

1. 面向多核的服务器编程时,多线程并不如多进程,因为对于每个进程来说,资源是独立的,切换core的时候无需考虑上下文; 而多线程中,每个线程共享资源,在core切换的时候,资源必须从一个core复制到另一个core才能继续运算。 换句话说,在cpu多核的情况下,多线程反而不如多进程。 ...
  • BlitzSkies
  • BlitzSkies
  • 2015-08-03 20:00
  • 714

linux下epoll模型应用介绍

第一讲 什么是epoll epoll是什么?按照man手册的说法:是为处理大批量句柄而作了改进的poll。当然,这不是2.6内核才有的,它是在2.5.44内核中被引进的(epoll(4) is a new API introduced in Linux kernel 2.5.44)。它几乎具备了...
  • chinawangfei
  • chinawangfei
  • 2015-04-15 10:29
  • 472

epoll模型及其框架(内附epoll 线程池项目代码)

在linux的网络编程中,很长的时间都在使用select来做事件触发。在linux新的内核中,有了一种替换它的机制,就是epoll。 相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率。因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗...
  • qq327767852
  • qq327767852
  • 2016-03-03 20:59
  • 981

分析Nginx epoll高效事件模型

首先Nginx支持以下这些事件模型:   Nginx支持如下处理连接的方法(I/O复用方法),这些方法可以通过use指令指定。   * select – 标准方法。 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数 –with-select_module 和 –wi...
  • shixiaoguo90
  • shixiaoguo90
  • 2014-04-04 14:28
  • 1690

网络通信服务器模型epoll/poll/select详解

同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的。所以先限定一下本文的上下文。 本文讨论的背景是Linux环境下的network IO。 一 概念说明 在进行解释之前,首先要说明几个概念: - 用户空间和...
  • tgxallen
  • tgxallen
  • 2017-03-04 16:10
  • 617

Apache select和Nginx epoll模型区别

部分内容摘自跟老男孩学Linux运维:Web集群实战(运维人员必备书籍)   /2561410/1752270 1.select 和epoll模型区别 .网络IO模型概述      通常来说,网络IO可以抽...
  • wma664620
  • wma664620
  • 2017-01-08 15:32
  • 1039
    我的GitHub
    个人资料
    • 访问:100890次
    • 积分:1983
    • 等级:
    • 排名:千里之外
    • 原创:95篇
    • 转载:40篇
    • 译文:0篇
    • 评论:8条
    最新评论