朴素、Select、Poll和Epoll网络编程模型实现和分析——Poll模型
在《朴素、Select、Poll和Epoll网络编程模型实现和分析——Select模型》中,我们分析了它只能支持1024个连接同时处理的原因。但是在有些需要同时处理更多连接的情况下,1024个连接往往是不够的,也就是不能够高并发。那么这个时候我们就可以采用本文介绍的Poll模型。(转载请指明出于breaksoftware的csdn博客)
在使用Poll模型之前,我们需要定义一个保存连接信息的数组
struct pollfd fds[FDS_COUNT];
之后创建异步监听socket、绑定端口和监听端口等行为和《朴素、Select、Poll和Epoll网络编程模型实现和分析——Select模型》一文中一模一样,本文就不列出代码了。我们把创建的socket信息赋值给fds数组的第一个元素,并且设定我们需要关注的事件POLLIN——可读。
int timeout;int cur_fds_count;int rc;int index;int expect_events;int error_events;
……// 创建socketmemset(fds, 0, sizeof(fds));error_events = POLLERR | POLLNVAL;expect_events = POLLIN;fds[0].fd = listen_sock;fds[0].events = expect_events;cur_fds_count = 1;
cur_fds_count用于记录当前fds数组中有多少个被关心的文件描述符。因为一开始我们只关心监听socket,所以它的初始值是1。
然后我们就要在一个死循环中,不停的调用poll函数,监控我们关心的文件描述符是否发生了状态改变
timeout = (500); while (1) {rc = poll(fds, cur_fds_count, timeout);if (rc < 0) {perror("poll error\n");exit(EXIT_FAILURE);};if (rc == 0) {//perror("poll timeout\n");};
poll函数的返回值和select函数类似。如果返回小于0,则说明发生了错误,我们让程序退出。如果返回了0,则说明poll函数超时。如果大于0,则说明被关心的文件描述符状态发生了改变。但是此时,我们仍然不知道是哪个文件描述符发生了改变,所以我们要遍历fds数组。
int cur_fds_count_temp = cur_fds_count;for (index = 0; index < cur_fds_count_temp; ++index) {
这个时候我们有必要说明下pollfd结构体的定义
struct pollfd {int fd;short events;short revents;
};
pollfd中的fd是用于记录我们关心的文件描述符;events表示我们关心的事件,如POLLIN、POLLOUT等。revents是实际发生的事件。于是我们一开始要判断改pollfd是否发生了事件改变
if (fds[index].revents == 0) {continue;}
接着我们判断下发生的事件是否是我们定义的出错事件。
if (fds[index].revents & error_events) {perror("revents error");
如果出错的是监听socket,则我们退出程序。
if (fds[index].fd == listen_sock) {perror("listen sock error");exit(EXIT_FAILURE);}
如果出错的不是监听socket,则它就是客户端接入的socket,我们将它关闭,并且将fds数组的最后一个元素覆盖当前位置,让数组长度减一。这个过程是最精简的数组缩小方式,如果使用新数组去记录,将导致效率降低。
else {close(fds[index].fd);cur_fds_count--;if (index < cur_fds_count) {memcpy(&fds[index], &fds[cur_fds_count], sizeof(fds[cur_fds_count]));memset(&fds[cur_fds_count], 0, sizeof(fds[cur_fds_count]));index--;}cur_fds_count_temp--;continue;} }
我们再看发生的事件是否是我们关心的事件,如果不是,则continue掉,继续处理下一个pollfd。
if (!(fds[index].revents & fds[index].events)) {continue;}
经过上述筛选,剩下的就是我们要正常处理的pollfd了。和Select方式一样,我们先看看其是否是监听socket。如果是,则获取客户端接入的socket值,并记录到数组中。
if (fds[index].fd == listen_sock) {int new_sock;new_sock = accept(listen_sock, NULL, NULL);if (new_sock < 0) {//perror("accept error");if (errno != EWOULDBLOCK) {continue;}exit(EXIT_FAILURE);}else {request_add(1);//set_block_filedes_timeout(new_sock);if (cur_fds_count + 1 < sizeof(fds)) {fds[cur_fds_count].fd = new_sock;fds[cur_fds_count].events = expect_events;cur_fds_count++;}}}
如果不是监听socket,则是客户端接入的socket。我们就读取这个socket中的内容,并写入我们的回包。
else {if (0 == server_read(fds[index].fd)) {server_write(fds[index].fd);}close(fds[index].fd);cur_fds_count--;if (index < cur_fds_count) {memcpy(&fds[index], &fds[cur_fds_count], sizeof(fds[cur_fds_count]));memset(&fds[cur_fds_count], 0, sizeof(fds[cur_fds_count]));index--;}cur_fds_count_temp--;}}}return 0;
}
如此,我们便将简单的poll服务器给写完了。我们看下poll模型的处理能力。采用和《朴素、Select、Poll和Epoll网络编程模型实现和分析——朴素模型》一文中相同的环境和压力,我们看下服务器的数据输出
再看下客户端的输出
可见当前环境下poll模型的处理能力大概是每秒7500次请求。
相关文章:

flashcom中远程共享对象SharedObject的用法
觉得这篇文章比较好,转载回来。学习fcs也有差不多一个月了,感觉最有特色的东西还是SharedObject.SharedObject有不少东西,本地操作就不说了(相信很多人没接触fcs也用过);就说说远程共享对象吧.基本的应用流程是:my_nc new NetConnection(); my_nc.connect("rt…

Hive-1.2.0学习笔记(一)安装配置
鲁春利的工作笔记,好记性不如烂笔头下载hive:http://hive.apache.org/index.htmlHive是基于Hadoop的一个数据仓库工具,提供了SQL查询功能,能够将SQL语句解析成MapReduce任务对存储在HDFS上的数据进行处理。MySQ安装Hive有三种运行…

邮件安全隐患及其防范技术研究
邮件安全隐患及其防范技术研究<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />陈小兵【antian365.com】摘要电子邮件是Internet上使用最为频繁和广泛的服务,在给人们带来便利的同时,亦带来令人担忧的邮件…
必看!52篇深度强化学习收录论文汇总 | AAAI 2020
所有参与投票的 CSDN 用户都参加抽奖活动群内公布奖项,还有更多福利赠送来源 | 深度强化学习实验室(ID:Deep-RL)作者 | DeepRLAAAI 2020 共收到的有效论文投稿超过 8800 篇,其中 7737 篇论文进入评审环节,最终收录数量…
朴素、Select、Poll和Epoll网络编程模型实现和分析——Epoll模型
在阅读完《朴素、Select、Poll和Epoll网络编程模型实现和分析——Select模型》和《朴素、Select、Poll和Epoll网络编程模型实现和分析——Poll模型》两篇文章后,我们发现一个问题,不管select函数还是poll函数都不够智能,它们只能告诉我们成功…

Scala 深入浅出实战经典 第88讲:Scala中使用For表达式实现map、flatMap、filter
高级函数 map,flatMap,filter用for循环的实现。package com.dt.scala.forexpressionobject For_Advanced {def main(args: Array[String]) {}def map[A, B](list: List[A], f: A > B): List[B] for(element <- list) yield f(element)def flatMap[A, B](list: List[A], f…
抛弃Python,我们为什么用Go编写机器学习架构?
所有参与投票的 CSDN 用户都参加抽奖活动群内公布奖项,还有更多福利赠送作者 | Caleb Kaiser译者 | 弯月,编辑 | 郭芮来源 | CSDN(ID:CSDNnews)如今,众所周知Python是机器学习项目中最流行的语言。尽管R、C…
朴素、Select、Poll和Epoll网络编程模型实现和分析——模型比较
经过之前四篇博文的介绍,可以大致清楚各种模型的编程步骤。现在我们来回顾下各种模型(转载请指明出于breaksoftware的csdn博客) 模型编程步骤对比《朴素、Select、Poll和Epoll网络编程模型实现和分析——朴素模型》中介绍的是最基本的网络编程…

使用VM虚拟机的一点小技巧
今天想为朋友弄一个虚拟机系统文件,这样就可以直接拷贝过去,直接让他用了。哪成想电脑里的系统镜像文件不能用,也不知道是不是VM不支持,反正怎么着也引导不起来了。无奈只好用硬件光驱来装虚拟系统,把2003系统盘装入光…
翻译:AKKA笔记 - Actor消息 -1(二)
消息 我们只是让QuoteRequest到ActorRef去但是我们根本没见过消息类! 它是这样的:(一个最佳实践是把你的消息类包装在一个完整的对象里以利于更好的组织) TeacherProtocol package me.rerun.akkanotes.messaging.protocolsobject …

远程安装oracle 10.2.1 for redhat 5.0 2.6.18-53.el5xen
远程安装oracle <?xml:namespace prefix st1 ns "urn:schemas-microsoft-com:office:smarttags" />10.2.1 for redhat 5.0 2.6.18-53.el5xen<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />今天有个朋友打电…
伯克利新无监督强化学习方法:减少混沌所产生的突现行为
作者 | Glen Berseth译者 | Arvin编辑 | 夕颜出品 | AI科技大本营(ID: rgznai100)【导读】所有生命有机体都在环境中占据一席之地,使它们在周围不断增加的熵中可以保持相对可预测性。例如,人类竭尽全力保护自己免受意外袭击--我们…
朴素、Select、Poll和Epoll网络编程模型实现和分析——Poll、Epoll模型处理长连接性能比较
在《朴素、Select、Poll和Epoll网络编程模型实现和分析——模型比较》一文中,我们分析了各种模型在处理短连接时的能力。本文我们将讨论处理长连接时各个模型的性能。(转载请指明出于breaksoftware的csdn博客) 我们可以想象下场景,…

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存在的一些问题,以及调试器需要的一些高级功能,我们还需要对这些接口进行…