关于EPoll的个人理解
1.epoll 是I/o多路复用的一种解决方案,对比select的优点有:
a.支持打开最大的文件描述符(可高达百万)
b.效率并不随着描述符的增多而线性下降。select每次是轮询,所以描述符越多效率越低。epoll的好处是利用事件触发,内核通过回调函数帮他(这是亲儿子)。
c.采用了mmap内存映射,减少内核区到用户区数据拷贝,又节省了不少时间。
2.Epoll又分为水平触发和边缘触发。
Level_triggered(水平触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据一次性全部读写完(如读写缓冲区太小),那么下次调用 epoll_wait()时,它还会通知你在上没读写完的文件描述符上继续读写,当然如果你一直不去读写,它会一直通知你!!!如果系统中有大量你不需要读写的就绪文件描述符,而它们每次都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率!!!
Edge_triggered(边缘触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll_wait()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你!!!这种模式比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符!!!
优缺点就很明显了,如过访问量过大,切每个事件的内容又很多的话,推荐边缘触发,因为每个事件的读取时要花长时间的,用边缘触发能明显减少事件的触发次数。
3.瓶颈。网上看的,不过倒是和我们的游戏服务器的限制想吻合。
单线程epoll,触发量可达到15000,但是加上业务后,因为大多数业务都与数据库打交道,所以就会存在阻塞的情况,这个时候就必须用多线程来提速。
代码实现:从服务端分析,什么时候该监听读,什么时候该监听写?(面试被问到过。。。)。从服务器的角度,客户端发送的请求都是需要读取的,所以是读事件,而服务器的返回数据是写事件。正常情况下应该是先读后写,有请求才返回嘛。写完之后这个描述符应该再切换回读事件,监听下次的请求。而且读是个被动事件,写是服务器的主动事件。所以网上大部分代码的实现都是默认监听读,服务器返回数据时将描述符置为写,写完后在还原读。
if(events[i].data.fd==listenfd)
{ connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen);
if(connfd<){
perror("connfd<0");
exit();
}
setnonblocking(connfd); char *str = inet_ntoa(clientaddr.sin_addr);
//std::cout<<"connec_ from >>"<
//设置用于读操作的文件描述符 ev.data.fd=connfd;
//设置用于注测的读操作事件 ev.events=EPOLLIN|EPOLLET;
//注册ev epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);
}
else if(events[i].events&EPOLLIN)
{
//printf("reading!/n"); if ( (sockfd = events[i].data.fd) < ) continue;
new_task=new task();
new_task->fd=sockfd;
new_task->next=NULL;
//添加新的读任务 pthread_mutex_lock(&mutex);
if(readhead==NULL)
{
readhead=new_task;
readtail=new_task;
}
else
{
readtail->next=new_task;
readtail=new_task;
}
//唤醒所有等待cond1条件的线程 pthread_cond_broadcast(&cond1);
pthread_mutex_unlock(&mutex);
}
else if(events[i].events&EPOLLOUT)
{
rdata=(struct user_data *)events[i].data.ptr;
sockfd = rdata->fd;
write(sockfd, rdata->line, rdata->n_size);
delete rdata;
//设置用于读操作的文件描述符
ev.data.fd=sockfd;
//设置用于注测的读操作事件
ev.events=EPOLLIN|EPOLLET;
//修改sockfd上要处理的事件为EPOLIN
epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
}
关于EPoll的个人理解的更多相关文章
- 五种I/O 模式,select、epoll方法的理解,BIO、NIO、AIO理解 相关文章
一.io方式 Linux网络编程 五种I/O 模式及select.epoll方法的理解 web优化必须了解的原理之I/o的五种模型和web的三种工作模式 五种I/O 模式——阻塞(默认IO模式),非阻 ...
- IO复用的三种方法(select,poll,epoll)深入理解
(一)IO复用是Linux中的IO模型之一,IO复用就是进程告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程处理,从而不会在单个IO上阻塞了,Linux中,提供 ...
- Linux epoll源码--
Linux系统运行源码剖析-epoll代码注释 理解了中断.等待队列.调度,你就能懂Linux的80%. --老子 转发的话,请注明出处哦:http://www.cnblogs.com/stoneha ...
- linux下编程epoll实现将GPS定位信息上报到服务器
操作系统:CentOS 开发板:fl2440 开发模块:A7(GPS/GPRS),RT3070(无线网卡) ********************************************** ...
- select,poll,epoll最简单的解释
从事服务端开发,少不了要接触网络编程.epoll 作为 Linux 下高性能网络服务器的必备技术至关重要,nginx.Redis.Skynet 和大部分游戏服务器都使用到这一多路复用技术. epoll ...
- 【转】转载一篇优质的讲解epoll模型的文章
从事服务端开发,少不了要接触网络编程.Epoll 作为 Linux 下高性能网络服务器的必备技术至关重要,Nginx.Redis.Skynet 和大部分游戏服务器都使用到这一多路复用技术. Epoll ...
- Nginx 介绍
Nginx 是什么 Nginx ("engine x") 是一个开源的,支持高性能.高并发的 Web 服务和代理服务软件.它是由俄罗斯人 Igor Sysoev 开发的,最初被应用 ...
- 学习 Tornado
异步编程 预习 lambda Lambda functions can be used wherever function objects are required. They are syntact ...
- memcached使用libevent 和 多线程模式
一.libevent的使用 首先我们知道,memcached是使用了iblievet作为网络框架的,而iblievet又是单线程模型的基于linux下epoll事件的异步模型.因此,其基本的思想就是 ...
随机推荐
- 优雅的使用Laravel之phpstorm配置
优雅的使用Laravel之phpstorm配置 先打开一个Laravel 项目,然后在project tool 窗口选择根节点.然后右键->Composer | Init composer . ...
- POJ1273:Drainage Ditches(最大流入门 EK,dinic算法)
http://poj.org/problem?id=1273 Description Every time it rains on Farmer John's fields, a pond forms ...
- hdu6158 The Designer
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6158 题目: The Designer Time Limit: 8000/4000 MS (J ...
- Java Character 类
Character 类用于对单个字符进行操作. Character 类在对象中包装一个基本类型 char 的值 实例 char ch = 'a'; // Unicode 字符表示形式 char uni ...
- mongoose 操作一直转圈
可能是:渲染时候 new content({ category:req.body.category, title:req.body.title, description:req.body.descri ...
- this指向 - 总结
/* 总结: this 的指向: 1.this 的指向 是在执行上下文时才确定的, 并且确定后不可更改: 2.this 指向 “其执行上下文的环境对象”; “其执行上下文的环境对象” 判读依据如下: ...
- MySQL中的索引的引用
博文首先说明索引的分类及创建,然后会涉及到索引的可用性选择以及索引的优化. 索引是什么?先说创建索引的目的,创建索引是为提高对数据的查询速度.在字典的目录中,我们可以很快找到某个字的位置,索引的作用就 ...
- linux各版本基线检查脚本(centos6、centos7、ubuntu系列)
以下是centos7基线检查脚本: #!/bin/bash #version v1. by pensar #操作系统linux 配置规范--centos7 cat <<EOF ****** ...
- 【各类MQ比较】消息队列MQ
目前业界有很多MQ产品,我们作如下对比: RabbitMQ 是使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP, STOMP,也正是如此,使的它变的非常重量 ...
- luogu p1101 单词方阵
https://www.luogu.org/problem/show?pid=1101 很恶心的代码 就是八个方向都搜索 #include<bits/stdc++.h> using na ...