朴素、Select、Poll和Epoll网络编程模型实现和分析——Poll、Epoll模型处理长连接性能比较
在《朴素、Select、Poll和Epoll网络编程模型实现和分析——模型比较》一文中,我们分析了各种模型在处理短连接时的能力。本文我们将讨论处理长连接时各个模型的性能。(转载请指明出于breaksoftware的csdn博客)
我们可以想象下场景,如果我们使用朴素模型来处理长连接,则需要引入多线程来处理:主线程接收接入的Socket,子线程处理一个个Socket的读写。因为长连接需要客户端和服务器之间维系一段时间,所以服务器子线程要一直同步等待socket的改变。如果socket长时间没有变化,那么这个子线程就将长期处于闲置状态,这无疑是对资源的一种浪费。然而此时Select、Poll和Epoll模型就能很好的解决这个问题,因为它是异步事件通知模式,所以不需要大量的线程同步等待,可以很好的利用线程资源。
因为我不想引入多线程协助处理,而朴素模型在处理长连接的情况下需要多线程协助,所以我没有将朴素模型列入之后的对长连接支持的改造。还有我也不打算对Select模型代码进行改造,因为我们之前已经分析过,Select模型只能处理一定数量的长连接,所以在高并发的场景下,它也没法使用。于是我们需要改造的是Poll和Epoll模型的代码,其实修改非常简单,我们只要将之前写完回包操作之后的关闭连接给去掉即可。
下一步,我们要对客户端进行改造。为了让客户端足够高效的利用线程资源,我们将客户端也改成Epoll模型。
void* send_data(void* arg) {int wait_time;int epfd, nfds;int client_sock;struct epoll_event ev, events[SOCKET_LIST_COUNT];int in_events, out_events;int index;wait_time = *(int*)arg;in_events = EPOLLIN | EPOLLET;out_events = EPOLLOUT | EPOLLET;epfd = epoll_create1(0);for (index = 0; index < 100; index++) {client_sock = make_client_socket();connect_server(client_sock);set_nonblock(client_sock);request_add(1);ev.data.fd = client_sock;ev.events = in_events;epoll_ctl(epfd, EPOLL_CTL_ADD, client_sock, &ev);client_write(client_sock);ev.events = in_events;epoll_ctl(epfd, EPOLL_CTL_MOD, client_sock, &ev);} while (1) {nfds = epoll_wait(epfd, events, sizeof(events), 500);usleep(wait_time);for (index = 0; index < nfds; ++index) {int fd = events[index].data.fd;if (events[index].events & EPOLLIN) {if (0 != client_read(fd)) {close(fd);epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);}else {events[index].events = out_events;epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &events[index]);}}else if (events[index].events & EPOLLOUT) {client_write(fd);events[index].events = in_events;epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &events[index]);}}}close(epfd);
}
我们只对线程函数进行修改。让一个线程新建100个socket去连接服务器,并使用Epoll模型去管理这些socket。
由于我的环境默认只能同时处理1024个连接,所以我使用ulimit -n 3000指令修改了该值,以让我们服务器可以同时处理3000个连接(实际上不到3000个,因为系统还要占用几个)。
最后在3个终端中使用./epoll_client 10 10指令启动客户端,让客户端启动30个线程,共新建3000个长连接。这3000个长连接每隔10微秒向服务器发送和接收一次数据。我们看下Poll模型的稳定时的表现
平均每秒处理27222次“读和写”操作。我们再看下EPoll模型的表现
平均每秒处理18876次“读和写”操作。
我们非常惊讶的发现Epoll模型竟然比Poll模型差!我们使用varlgrind对两种模型进行分析
Poll模型的main函数自身耗时占比仅为12.11%。其主要是读写操作的占用。而其执行循环的次数是 10 113 131次,有效循环是8 374 693次,有效率是82.2%。这个比例还是不错的。
我们再看Epoll模型的统计结果
Epoll模型的main函数自身占用26.56%,这个比例是Poll模型的两倍。其中循环次数和有效循环次数一致,故有效率是100%。
通过上面的对比,我们可以推定就是main函数自身的耗时影响了Epoll模型的效率。
和《朴素、Select、Poll和Epoll网络编程模型实现和分析——模型比较》中对Poll和Epoll模型的性能统计分析,我们发现Poll模型的main函数自身耗时占比有明显的变化,前文是46.93%,本文是12.11%。而Epoll模型的main函数自身耗时占比则比较稳定,前文是25.7%,本文是26.56%。
我们再看下CPU和内存的情况
可以发现当前测试环境下两个模型的CPU和内存占用情况是相差不大的。
经过以上分析,我们可以发现在处理长连接时,如果同时连接数量不是很大,且长连接通信频繁时,Poll模型的效率是比Epoll高的。
那么什么时候Epoll效率最高呢?对比Poll和Epoll模型,我们发现Poll模型中有效循环的比例会随着连接数量上涨、通信频度下降而下降。于是我们模拟大量长连接,通信频度不高的场景。
为了能支持高并发,我们需要对我们的系统设置进行一些修改。我的测试环境是Ubuntu Server 14,网上有一篇博文《Ubuntu 12 ulimit 系统最大打开文件个数 设置》,我按此博文介绍将我的环境下的最大连接数改成了40960。这一步非常必要。
我们使用,/epoll_client 200 1000000指令启动20个线程,供建立20000个连接,各个连接每一秒钟发送一次请求。
我们看下Poll模型的表现
Poll模型平均每秒完成6665次“读和写”操作,且CPU占用率高达65%。
再看下Epoll模型的表现
Epoll模型平均每秒完成6871次“读和写”操作,而CPU占用率只有8.6%。
上述现象说明在大量长连接、不频繁通信的情况下,Epoll模型比Poll模型在CPU消耗上要优秀非常多。
同样我们使用varlgrind分析这种场景下Poll模型和Epoll模型的耗时情况
首先看Poll模型
Poll模型的main函数自身耗时占了64.65%。总循环次数445 973 878,有效循环次数2 135 891,有效率0.48%。
再看看Epoll模型的统计结果
Epolll模型的main函数自身耗时还是稳定在26.57%。总循环次数和有效循环次数一致,故有效率100%。
网上还有很多关于Poll模型和Epoll模型在内核源码级别的对比,并指出Epoll模型的源码是多么的高效。但是使用varlgrind工具测试发现,其主要的性能差距是在无效循环的比例上。而内核源码导致的性能进步却没有明显体现。我们以strlen函数为参考进行对比就可以发现上述观点(可以认为不同程序里对相同内容空间进行strlen操作耗时是一样)。
Poll模型的strlen函数和poll函数的耗时占比是1.21:0.01=121。而Epoll模型中则是9.38:(2.36+0.23)=3.63。
经过这一系列博文的分析,我们可以大致掌握朴素、Select、Poll和Epoll模型的编程方法,同时也对不同场景下选择什么模型有了一定的认识。
最后附上代码链接:http://pan.baidu.com/s/1bTP7MQ 密码:0mc9
相关文章:

Topcoder SRM 663 DIV 1
ABBADiv1 题意: 规定两种操作,一种是在字符串的末尾添加A,另一种是在末尾添加B然后反转字符串。现在给你一个起始串,一个终点串,然后问你是否能够通过以上两种操作,从起始串变为终点串。 题解: …
跨平台PHP调试器设计及使用方法——立项
作为一个闲不住且希望一直能挑战自己的人,我总是在琢磨能做点什么。自从今年初开始接触PHP,我也总想能在这个领域内产生点贡献。那能做点什么呢?我经常看到很多phper说自己设计了一个什么框架,或者说自己搭建了一个什么系统。虽然…
机器推理文本+视觉,跨模态预训练新进展
作者 | 李根、段楠、周明来源 | 微软研究院AI头条(ID:MSRAsia)【导读】机器推理要求利用已有的知识和推断技术对未见过的输入信息作出判断,在自然语言处理领域中非常重要。本文将介绍微软亚洲研究院在跨模态预训练领域的研究进展。近年来&…

[LeetCode]:94:Binary Tree Inorder Traversal
题目: Given a binary tree, return the inorder traversal of its nodes values. For example:Given binary tree {1,#,2,3}, 1\2/3return [1,3,2]. 代码: public class Solution {public static ArrayList<Integer> listResult new ArrayList&l…
腾讯 AI 2019这一年
所有参与投票的 CSDN 用户都参加抽奖活动群内公布奖项,还有更多福利赠送近日,腾讯AI实验室总结了 2019 年其取得重大进展的两大研究方向,推动实现的行业应用以及前沿研究探索方面的成果。一、两大难题攻坚:通用人工智能与数字人用…
跨平台PHP调试器设计及使用方法——探索和设计
在《跨平台PHP调试器设计及使用方法——立项》一文中,我确定了使用xdebug作为调试器插件部分的基础组件。xdebug提供了一个远程调试的功能(相关资料可以详见https://xdebug.org/docs/remote),我们这个项目便是基于这个功能实现的。…

Ubuntu下允许Root用户直接登录图形界面
ubuntu root是默认禁用了,不允许用root登陆,所以先要设置root密码。 执行:sudo passwd root 接着输入密码和root密码,重复密码。再重新启动就可以用root登陆。 另外,默认情况下是不允许用root帐号直接登陆图形界面的。…

携程App for Apple Watch探索
在Apple Watch发布之后,很多App都针对它设计了相应的版本。旅行作为与Apple Watch时间管理特性契合度较高的场景,同时携程旅行作为国内领先的OTA行业App,也成为了首批适配Apple Watch并荣登Apple官网和App Store推荐的应用之一。InfoQ就App f…
跨平台PHP调试器设计及使用方法——通信
首先引用《跨平台PHP调试器设计及使用方法——探索和设计》中的结构图(转载请指明出于breaksoftware的csdn博客) 本文要介绍的是我们逻辑和pydbgp通信的实现(图中红框内内容)。 设计通信之前,我需要先设计一种通信协议…

MVP模式的相关知识
MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Mod…
“数学不行,还能干点啥?”面试官+CTO:干啥都费劲!
关于数学与程序员的“暧昧”关系,先看看网友的看法:同时编程圈也流传着一个段子:一流程序员靠数学,二流程序员靠算法,末端程序员靠百度,低端看高端就是黑魔法。想一想,我们日常学习、求职、工作…

CentOS7 yum 源的配置与使用
YUM:Yellowdog Updater Modified Yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖…

跨平台PHP调试器设计及使用方法——协议解析
在《跨平台PHP调试器设计及使用方法——探索和设计》一文中,我介绍了将使用pydbgp作为和Xdebug的通信库,并让pydbgp以(孙)子进程的方式存在。《跨平台PHP调试器设计及使用方法——通信》解决了和pydbgp通信的问题,本文…

测试客户端发图图
转载于:https://blog.51cto.com/ericsong/116942
搜狐、美团、小米都在用的Apache Doris有什么好? | BDTC 2019
【导读】12 月 5-7 日,由中国计算机学会主办,CCF 大数据专家委员会承办,CSDN、中科天玑协办的中国大数据技术大会(BDTC 2019)在北京长城饭店隆重举行。100 顶尖技术专家、1000 大数据从业者齐聚于此,以“大…

cacti邮件告警设置
功能说明对指定流量图形(指定接口)设置最高或最低流量阀值,当流量出现异常偏高或偏低触发阀值,系统自动将异常信息以邮件形式通知指定收件人。如果收件人邮箱是139邮箱,还可以增设短信通知功能。设置前准备设置该功能之…
跨平台PHP调试器设计及使用方法——高阶封装
在《跨平台PHP调试器设计及使用方法——协议解析》一文中介绍了如何将pydbgp返回的数据转换成我们需要的数据。我们使用该问中的接口已经可以构建一个简单的调试器。但是由于pydbgp存在的一些问题,以及调试器需要的一些高级功能,我们还需要对这些接口进行…

Oracle的口令文件(passwordfile)的讲解(摘录)
初学oracle,很多概念迷糊,今天看到这文章,让我有一个比较清晰的认识。转载[url]http://www.itpub.net/viewthread.php?tid906008&extra&page1[/url]1、os认证oracle安装之后默认情况下是启用了os认证的,这里提到的os认证…
如何优雅地使用pdpipe与Pandas构建管道?
作者 | Tirthajyoti Sarkar译者 | 清儿爸编辑 | 夕颜出品 | AI科技大本营(ID: rgznai100) 【导读】Pandas 是 Python 生态系统中的一个了不起的库,用于数据分析和机器学习。它在 Excel/CSV 文件和 SQL 表所在的数据世界与 Scikit-learn 或 Te…

第 十 天 : 添 加 硬 盘 和 分 区 挂 载 等
小Q:狼若回头,必有缘由,不是报恩,就是***; 事不三思必有败,人能百忍则无忧。今天的进度虽然慢了,但是学习状态还是一如往常,只不过今天遇到了不少新的知识点,需要好好想想…
从4个月到7天,Netflix开源Python框架Metaflow有何提升性能的魔法?
作者 | Rupert Thomas译者 | 凯隐编辑 | Jane出品 | AI科技大本营(ID:rgznai100)【导语】Metaflow 是由 Netflix 开发,用在数据科学领域的 Python框架,于 2019 年 12 月正式对外开源。据介绍,Metaflow 解决…
SOA标准发展混乱 国内业务缺少经验
近年来,SOA已经成为国际及我国信息技术领域的重大热点之一。从2005年至今,SOA逐渐成为影响中国IT系统构建的主导思想。从2006年开始,SOA的建设方法已在我国部分行业信息化项目中开始得以越来越广泛的应用。 但热潮背后, SOA概念在…
跨平台PHP调试器设计及使用方法——界面设计和实现
一个优秀的交互设计往往会影响一个产品的命运。在设计这款调试器时,我一直在构思这款调试器该长什么样子。简单、好用是我设计的原则,于是在《跨平台PHP调试器设计及使用方法——立项》一文中,我给出了一个Demo。之后实现的效果也与之变化并不…

AJAX安全-Session做Token
个人思路,请大神看到了指点 个人理解token是防止扫号机或者恶意注册、恶意发表灌水,有些JS写的token算法,也会被抓出来被利用,个人感觉还是用会过期的Session做token更好,服务器存储,加载到客户端页面&…
跨平台PHP调试器设计及使用方法——使用
经过之前六篇博文的分析和介绍,大家应该对这套调试器有个初步的认识。本文我将讲解它的使用方法。(转载请指明出于breaksoftware的csdn博客) 上图是该软件界面的布局,我们之后的讲解也将围绕着这些功能展开。 文件夹管理 在查看一…
管理7k+工作流,月运行超10000万次,Lyft开源的Flyte平台意味着什么?
作者 | Allyson Gale译者 | 刘畅编辑 | Jane出品 | AI科技大本营(ID:rgznai100)【导读】Flyte 平台可以更容易的创建并发,可伸缩和可维护的工作流,从而进行机器学习和数据处理。Flyte 已有三年多的训练模型和数据处理经…

Jmeter组件执行顺序与作用域
一、Jmeter重要组件: 1)配置元件---Config Element: 用于初始化默认值和变量,以便后续采样器使用。配置元件大其作用域的初始阶段处理,配置元件仅对其所在的测试树分支有效,如,在同一个作用域…
跨平台PHP调试器设计及使用方法——拾遗
之前七篇博文讲解了跨平台PHP调试器从立项到实现的整个过程,并讲解了其使用方法。但是它们并不能全部涵盖所有重要内容,所以新开一片博文,用来讲述其中一些杂项。(转载请指明出于breaksoftware的csdn博客) 触发调试的…
召唤超参调优开源新神器:集XGBoost、TensorFlow、PyTorch、MXNet等十大模块于一身...
整理 | 凯隐编辑 | Jane出品 | AI科技大本营(ID:rgznai100)【导读】Optuna是一款为机器学习任务设计的自动超参数优化软件框架,是一款按运行定义(define-by-run) 原则设计的优化软件,允许用户动态地调整搜索空间&#…

Linux下的Silverlight:Moonlight 1.0 Beta 1发布了
Moonlight是微软Silverlight的一个开源实现,其目标平台是Linux与Unix/X11系统。自从2007年9月开始,Moonlight就在Mono项目下进行了开发,它是由Novell发起并资助的。现在,Moonlight 1.0 Beta 1已经向公众发布了。 Novell和Mono宣布…