Linux高并发机制——epoll模型

epoll是一个特别重要的概念,常常用于处理服务端的并发问题。当服务端的在线人数越来越多,会导致系统资源吃紧,I/O效率越来越慢,这时候就应该考虑epoll了。epoll是Linux内核为处理大批句柄而作改进的poll,是Linux特有的I/O函数。其特点如下:

1.epoll是Linux下多路复用IO接口select/poll的增强版本。其实现和使用方式与select/poll有很多不同,epoll通过一组函数来完成有关任务,而不是一个函数。

2.epoll之所以高效,是因为epoll将用户关心的文件描述符放到内核里的一个事件表中,而不是像select/poll每次调用都需要重复传入文件描述符集或事件集。比如当一个事件发生(比如说读事件),epoll无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入就绪队列的描述符集合就行了。

3.epoll有两种工作方式,LT(level triggered):水平触发和ET(edge-triggered):边沿触发。LT是select/poll使用的触发方式,比较低效;而ET是epoll的高速工作方式。

通俗理解就是,比如说有一堆女孩,有的很漂亮,有的很凤姐。现在你想找漂亮的女孩聊天,LT就是你需要把这一堆女孩全都看一遍,才可以找到其中的漂亮的(就绪事件);而ET是你的小弟(内核)将N个漂亮的女孩编号告诉你,你直接去看就好,所以epoll很高效。另外,还记得我的上一篇文章中小明找女神聊天的例子吗?采用非阻塞方式,小明还需要每隔十分钟回来看一下(select);如果小明有小弟(内核)帮他守在大门口,女神回来了,小弟会主动打电话,告诉小明女神回来了,快来处理吧!这就是epoll。

epoll共有三个函数,如下:

[cpp] view plain copy

  1. 1、int epoll_create(int size)
  2. // 创建一个epoll句柄,参数size用来告诉内核监听的数目,size为epoll所支持的最大句柄数

[cpp] view plain copy

  1. 2、int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
  2. /*函数功能: epoll事件注册函数
  3.   参数epfd为epoll的句柄,即epoll_create返回值
  4.   参数op表示动作,用3个宏来表示:
  5.     EPOLL_CTL_ADD(注册新的fd到epfd),
  6.  EPOLL_CTL_MOD(修改已经注册的fd的监听事件),
  7.     EPOLL_CTL_DEL(从epfd删除一个fd);
  8.     其中参数fd为需要监听的标示符;
  9.   参数event告诉内核需要监听的事件,event的结构如下:*/
  10. struct epoll_event {
  11. __uint32_t events; //Epoll events
  12. epoll_data_t data; //User data variable
  13. };

[cpp] view plain copy

  1. 3、 int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout)
  2. //等待事件的产生,函数返回需要处理的事件数目(该数目是就绪事件的数目,就是前面所说漂亮女孩的个数N)

因此,服务端epoll的时候,步骤如下:

1.调用epoll_create函数在Linux内核中创建一个事件表;

2.然后将文件描述符(监听套接字)添加到所创建的事件表中;

3.在主循环中,调用epoll_wait等待返回就绪的文件描述符集合;

4.分别处理就绪的事件集合

下面介绍下如何将一个socket添加到内核事件表中,如下:

[cpp] view plain copy

    1. //将文件描述符fd添加到epollfd标示的内核事件表中, 并注册EPOLLIN和EPOOLET事件,EPOLLIN是数据可读事件;EPOOLET表明是ET工作方式。最后将文件描述符设置非阻塞方式
    2. /**
    3. * @param epollfd: epoll句柄
    4. * @param fd: 文件描述符
    5. * @param enable_et : enable_et = true,
    6. 采用epoll的ET工作方式;否则采用LT工作方式
    7. **/
    8. void addfd( int epollfd, int fd, bool enable_et )
    9. {
    10. struct epoll_event ev;
    11. ev.data.fd = fd;
    12. ev.events = EPOLLIN;
    13. if( enable_et )
    14. ev.events = EPOLLIN | EPOLLET;
    15. epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev);
    16. setnonblocking(fd);
    17. printf("fd added to epoll!\n\n");
    18. }
时间: 2024-10-12 18:23:38

Linux高并发机制——epoll模型的相关文章

GNU Linux高并发性能优化方案

/*********************************************************** * Author : Samson * Date : 07/14/2015 * Test platform: * gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2 * GNU bash, 4.3.11(1)-release (x86_64-pc-linux-gnu) * Nginx version: * Nginx 1.6.2 * Nginx 1.8.0

Linux 高并发服务器

高并发服务器 一.多进程并发服务器 1. 实现示意图 2. 使用多进程并发服务器时要考虑以下几点: 父进程最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符) 系统内创建进程个数(与内存大小相关) 进程创建过多是否降低整体服务性能(进程调度) 3. 使用多进程的方式, 解决服务器处理多连接的问题:     (1)共享 读时共享, 写时复制 文件描述符 内存映射区 -- mmap     (2)父进程 的角色是什么? 等待接受客户端连接 -- accept 有链接: 创建一

高并发的epoll+线程池,业务在线程池内

我们知道,服务器并发模型通常可分为单线程和多线程模型,这里的线程通常是指"I/O线程",即负责I/O操作,协调分配任务的"管理线程",而实际的请求和任务通常交由所谓"工作者线程"处理.通常多线程模型下,每个线程既是I/O线程又是工作者线程.所以这里讨论的是,单I/O线程+多工作者线程的模型,这也是最常用的一种服务器并发模型.我所在的项目中的server代码中,这种模型随处可见.它还有个名字,叫"半同步/半异步"模型,同时,这种

Linux高并发内核优化-TougheRadius

linux 内核优化 默认情况下,linux系统有一些限制,并不能直接支持高并发性能,需要做一些内核优化. 1.把以下内容加入 /etc/sysctl.conf 1 net.ipv4.ip_forward=1 2 net.ipv4.tcp_syncookies = 1 3 net.ipv4.tcp_tw_reuse = 1 4 net.ipv4.tcp_tw_recycle = 1 5 net.ipv4.tcp_fin_timeout = 30 6 net.ipv4.tcp_keepalive_

Java高并发-Java内存模型和线程安全

一.原子性 原子性是指一个操作是不可中断的.即使在多个线程一起执行的时候,一个操作一旦开始,就不会被其它线程干扰. i++是原子操作吗? 不是,包含3个操作:读i,i=i+1,写i 32位的机子上读取64位的long型也不是原子操作 二.有序性 2.1 举例 在并发时,程序的执行可能会出现乱序 2.2 步骤 一条指令的执行是可以分为很多步骤的: 取指IF 译码和取寄存器操作数ID 执行或者有效地址计算EX 存储器访问MEM 写回WB 流水线执行指令 分析: 指令分解成不同阶段 假设一条指令消耗一

Linux epoll 笔记(高并发事件处理机制)

wiki: Epoll优点: Epoll工作流程: Epoll实现机制: epollevent; Epoll源码分析: Epoll接口: epoll_create; epoll_ctl; epoll_close; Epoll工作方式: LT(level-triggered); ET(edge-triggered); Epoll应用模式; Epoll优点: <1>支持一个进程打开大数目的socket描述符(FD) select一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值

Nginx多进程高并发、低时延、高可靠机制在缓存代理中的应用

1. 开发背景 现有开源缓存代理中间件有twemproxy.codis等,其中twemproxy为单进程单线程模型,只支持memcache单机版和redis单机版,都不支持集群版功能. 由于twemproxy无法利用多核特性,因此性能低下,短连接QPS大约为3W,长连接QPS大约为13W,同时某些场景时延抖动厉害. 为了适应公有云平台上业务方的高并发需求,因此决定借助于twemproxy来做二次开发,把nginx的高性能.高可靠.高并发机制引入到twemproxy中,通过master+多work

2020.04.10 线上性能优化以及Linux下NIO/Epoll模型全解--实战

1.支付宝模拟线上优化实战 2.手写JUC工具与提升tomcat吞吐量 3.网络通信BIO设计与缺陷   -- accept()  和 read()阻塞 4.单线程解决高并发NIO精髓解读 5.OS内核下Epoll与Selete源码解读 第一部分: 性能优化 问题:如何在高并发场景下实现支付宝用户登录页面的信息获取?如用户信息,金额,积分等 浏览器  ---- Spring MVC ---- controller ----- service ---- 用户模块.余额模块.积分模块等 -- 调用多

1支持高并发web服务器搭建

支持高并发web服务器搭建 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] CTCDN系统优化参数 关闭ipv6 避免放大攻击 开启恶意icmp错误消息保护 关闭路由转发 开启反向路径过滤 处理无源路由的包 关闭sysrq功能 core文件名中添加pid作为扩展名 开启SYN洪水攻击保护 修改消息队列长度 设置最大内存共享段大小bytes timewait的数量默认180000 系统同时保持TIME_WAIT的最大数量如果超过这个数字TIME_WAIT将立刻被清除并打印警