select 和epoll模型区别

1.select epoll模型

1.1.IO模型概述

     通常来,网IO可以抽象成用户态和内核态之间的数据交换。一次网络数据读取操作(read),可以拆分成两个步骤:1)网卡驱动等待数据准备好(内核态)2)将数据从内核空间拷贝到进程空间(用户态)。根据这两个步骤处理方式不一样,我们通常把网络IO划分成阻塞IO和非阻塞IO。

      ·阻塞IO。用户调用网IO相关的系统调(例如read),如果此内核网卡没有取到网数据,那么本次系统调用将会一直阻塞,直到对端系统发送的数据到达为止。如果对端一直没有发送数据,则本次调用将永远不会返回。

      · 非阻塞IO。当用户调用网IO相关的系统调(例如read),如果此内核网络还没有收到网数据,那么本次系统调用将会立即返回,并返回一个EAGAIN错误码

在没有IO多路复用技之前,由于没有一种好的方式来探IO是否可可写。因此,了增加系的并发连接量,一般是借助多线程或多程的方式来增加系的并发连接数。但是种方式有个问题就是系的并发连接数受限于操作系的最大线程或程数,并且随着操作系线程或程数增加,将会引大量的上下文切致系的性能急下降。了解决问题,操作系引入了IO多路接技IO multiplexing)。

1.2.  IO多路技术

    IO多路转接技术其实就是使用select、epoll等操作系统提供的系统调用来检测IO事件的各种机制。通过select、epoll等机制,我们可以很轻松的同时管理大量的网络IO连接,并且获取到处于活跃状态的连接。当其中一个或多个发生网络IO事件时,select、epoll等系统调用就会返回相应的连接,我们就可以对这些连接进行读取或写入操作,从而完成网络数据交互。

1.3.select 工作原理

       select函数原型:

        int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

          select各个参数明:

               ·  nfds

这个参数的值一般设置为读集合(readfds)、写集合(writefds)以及exceptfds(异常集合)中最大的描述符(fd)+1,当然也可以设置为FD_SETSIZE。FD_SETSIZE是操作系统定义的一个宏,一般是1024。也就是说读写以及异常集合大小的最大值是1024,所以使用select最多只能管理1024个连接。如果大于1024个连接,select将会产生不确定行为。

· readfds

指向可读描述符集的指针,如果我们关心连接的可读事件,需要把连接的描述符设置到读集合中。

·writefds

指向可写描述符集的指,如果我关心接的可写事件,需要把接的描述符置到可写集合中。

· exceptfds

指向异常描述符集的指,如果我关心接的是否生异常,需要把接的描述符置到异常描述符集合中。

·timeout

select愿意等待的时间

                      struct timeval {

                                           longtv_sec;      //秒数

                                           longtv_usec;    //微秒数

                                   }

                一般来,分三种情况:

·timeout空,select将会永等待。直到有接可读、可写或者被信号中断时返回。

·timeout->tv_sec = 0 且 timeout->tv_usec = 0,完全不等待。检测所有指定的描述符后立即返回。这是得到多个描述符的状态而不阻塞select函数的轮询方法。

·timeout->tv_sec != 且 timeout->tv_usec != 0,等待指定的秒数和微秒数。当指定的描述符之一已经准备好,或者超过了指定的时间值,则立即返回。如果超时了,还没有一个描述符准备好,则返回0。

     select的工作原理,select过轮询来检测各个集合中的描述符fd)的状,如果描述符的状态发生改变,则会在该集合中设置相应的标记位;如果指定描述符的状态没有发生改变,则将该描述符从对应集合中移除。因此,select的调用复杂度是线性的,即O(n)。举个例子,一个保姆照看一群孩子,如果把孩子是否需要尿尿比作网络IO事件,select的作用就好比这个保姆挨个询问每个孩子:你要尿尿吗?如果孩子回答是,保姆则把孩子拎出来放到另外一个地方。当所有孩子询问完之后,保姆领着这些要尿尿的孩子去上厕所(处理网络IO事件)。

    select的限制,前面提到FD_SETSIZE宏,这个宏是操作系统定义的。在linux下面通常是1024,也就是说select最多只能管理1024个描述符。如果大于1024的个描述,select将会产生不可预知的行为。那在没有poll或epoll的情况下,怎样使用select来处理连接数大于1024的情况呢?答案是使用多线程技术,每个线程单独使用一个select进行检测。这样的话,你的系统能够处理的并发连接数等于线程数*1024。早期的apache就是这种技术来支撑海量连接的。

1.4.epoll工作原理

  epoll函数原型:

        int epoll_create(int size);

        intepoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

 

                int epoll_wait(intepfd,  struct epoll_event *events, intmaxevents,  int timeout);

         epoll上述三个函数,既可以完成成千上万的并发连接管理。epoll使用方式,1)通epoll_create建立epoll句柄。2)将描述符所感趣的事件通epoll_ctl添加到epoll句柄中。3epoll_wait返回所有可写的描述符。

  epollLinux内核为处理大批量文件描述符而作了改epoll,是Linux下多路复用IO接口select/poll的增版本,它能著提高程序在大量发连中只有少量活的情况下的系CPU利用率。另一点原因就是取事件的候,它无整个被听的描述符集,只要遍那些被内核IO事件异步醒而加入Ready列的描述符集合就行了。epoll除了提供select/poll那种IO事件的水平触Level Triggered)外,提供了边缘Edge Triggered),就使得用程序有可能IO,减少epoll_wait/epoll_pwait用,提高用程序效率。

      还是以保姆照看一群孩子为例,在epoll机制下,保姆不再需要挨个的询问每个孩子是否需要尿尿。取而代之的是,每个孩子如果自己需要尿尿的时候,自己主动的站到事先约定好的地方,而保姆的职责就是查看事先约定好的地方是否有孩子。如果有小孩,则领着孩子去上厕所(网络事件处理)。因此,epoll的这种机制,能够高效的处理成千上万的并发连接,而且性能不会随着连接数增加而下降。

1.5.selectepoll

上所述,selectepoll比如下表所示


select

epoll

性能

随着接数增加,急下降。理成千上万并发连接数,性能很差。

随着接数增加,性能基本上没有下降。理成千上万并发连,性能很好。

接数

连接数有限制,处理的最大连接数不超过1024。如果要处理超过1024个连接数,则需要修改FD_SETSIZE宏,并重新编译 。

接数无限制。

内在处理机制

线性轮询

回调callback

开发复杂性

 

老男孩教育:selectepoll简单区别比喻

select的调用复杂度是线性的,即O(n)。举个例子,一个保姆照看一群孩子,如果把孩子是否需要尿尿比作网络IO事件,select的作用就好比这个保姆挨个询问每个孩子:你要尿尿吗?如果孩子回答是,保姆则把孩子拎出来放到另外一个地方。当所有孩子询问完之后,保姆领着这些要尿尿的孩子去上厕所(处理网络IO事件)。

还是以保姆照看一群孩子为例,在epoll机制下,保姆不再需要挨个的询问每个孩子是否需要尿尿。取而代之的是,每个孩子如果自己需要尿尿的时候,自己主动的站到事先约定好的地方,而保姆的职责就是查看事先约定好的地方是否有孩子。如果有小孩,则领着孩子去上厕所(网络事件处理)。因此,epoll的这种机制,能够高效的处理成千上万的并发连接,而且性能不会随着连接数增加而下降。











本文转自 蓝叶子Sheep 51CTO博客,原文链接:http://blog.51cto.com/dellinger/1952776,如需转载请自行联系原作者

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/279196.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python数据结构与算法第六讲_Python 学习 -- 数据结构与算法 (六)

栈 是一种 “操作受限”的线性表,只允许在一端插入和删除数据。从功能是上来说,数组和链表确实可以替代栈,但是特定的数据结构是对特定场景的抽象,而且,数组或链表暴露了太多的操作接口,操作上的确灵活自由…

spring-springmvc code-based

idea设置maven在下载依赖的同时把对应的源码下载过来。图0:1主要实现零配置来完成springMVC环境搭建,当然现在有了springBoot也是零配置,但是很多同仁都是从spring3.x中的springMVC直接过渡到springBoot的,spring3.x的MVC大部分都…

powershell 入门_使用PowerShell入门的5个Cmdlet

powershell 入门PowerShell is quickly becoming the preferred scripting language and CLI of Power Users as well as IT Pros. It’s well worth learning a few commands to get you started, so we’ve got 5 useful cmdlets for you to learn today. PowerShellSwift成为…

Part 3: Services

介绍 在第3部分中,我们将扩展应用程序并启用负载平衡。为此,我们必须在分布式应用程序的层次结构中提升一个级别:服务。 StackServices (你在这里)Container (涵盖在第2部分中)关于服务 在分布式应用程序中,应用程序的不同部分被称为“服务”…

mysql ldf文件太大_Linux_数据库清除日志文件(LDF文件过大),清除日志: 复制代码 代码如 - phpStudy...

数据库清除日志文件(LDF文件过大)清除日志:复制代码 代码如下:DECLARE LogicalFileName sysname,MaxMinutes INT,NewSize INTUSE szwzcheck -- 要操作的数据库名SELECT LogicalFileName szwzcheck_Log, -- 日志文件名MaxMinutes 10, -- Limit on time allowed to …

emwin之错误使用控件函数导致死机现象

2018-10-15 导致死机的代码示例如下 1 /**2 * brief widget ID define3 * {4 */5 6 #define ID_WINDOW_0 (GUI_ID_USER 0x00)7 #define ID_TEXT_0 (GUI_ID_USER 0x01)8 #define ID_TEXT_1 (GUI_ID_USER …

diy感应usb摄像头拍照_DIY无线感应充电器

diy感应usb摄像头拍照Courtesy of Instructables user Inducktion shares a very detailed tutorial on how to build a wireless power charger. He explains the impetus behind the project: 由Instructables用户提供Inducktion分享了有关如何构建无线电源充电器的非常详细…

ubuntu7.10安装到3D开启

累了好几天,重装了十几遍终于把ubuntu7.10搞定到了我自认为完美的状态了。现在总结一下安装过程(按操作顺序记录):1.在xp下不管用pqmajac还是其他硬盘分区工具分出10G的空余分区来(实验阶段10G尝试下)&…

初学者对python的认识_Python初学者列表,python,初识

1.认识列表列表可以放入所有我们目前学习过的数据类型,甚至包括列表2.有关列表的方法、内置函数(设列表的名称为list)向列表中添加元素:append():list.append(要添加的元素),注意每次只能添加一个元素,被添加的元素自动…

常用模块之 time,datetime,random,os,sys

time与datetime模块 先认识几个python中关于时间的名词: 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。1970年之前的日期无法以此表…

使用aSpotCat控制您的Android应用权限

Viewing the permissions of each installed Android app requires digging through the Manage Applications screen and examining each app one by one — or does it? aSpotCat takes an inventory of the apps on your system and the permissions they require. 要查看每…

xtrabackup备份mysql“ib_logfile0 is of different”错误分析

今天用xtrabackup工具完整备份mysql数据库的时候出现“./ib_logfile0 is of different”错误,具体的日志信息如下: 我第一时间查询了百度和谷歌都没有找见相对应的答案。决定从错误日志入手,上面的日志提示说:mysql数据库inondb的日志文件的大…

java socket 报文解析_java socket解析和发送二进制报文工具(附java和C++转化问题)

解析:首先是读取字节:/*** 读取输入流中指定字节的长度* * 输入流**paramlength 指定长度*return指定长度的字节数组*/public static byte[] readBytesFromTo(byte[] buffer, int from, intlength) {byte[] sub new byte[length];int cur 0;for (int i from; i < length …

Ubuntu防火墙:ufw

原始linux的防火墙是iptables&#xff0c;以为过于繁琐&#xff0c;各个发行版几乎都有自己的方案; ubuntu下的防火墙是ufw[ubuntu fireward的缩写]&#xff0c;centos的防火墙是fireward ubuntu下&#xff1a; 启用或者关闭防火墙 sudo ufw enable|disable sudo ufw default d…

如何使自己的不和谐机器人

Discord has an excellent API for writing custom bots, and a very active bot community. Today we’ll take a look at how to get started making your own. Discord具有出色的用于编写自定义机器人的API&#xff0c;以及非常活跃的机器人社区。 今天&#xff0c;我们将探…

​css3属性选择器总结

css3属性选择器总结 &#xff08;1&#xff09;E[attr]只使用属性名&#xff0c;但没有确定任何属性值 <p miaov"a1">111111</p> <p miaov"a2">111111</p> p[miaov]{background: red;} /*所有属性为miaov的元素都会被背景变红&a…

java复合赋值运算符_Java 之复合赋值运算符

1.引入问题切入正题&#xff0c;看下面代码&#xff0c;结果应该是怎么样的public class App{public static void main( String[] args ){byte a1 ;int b 10;a ab;System.out.println(a);ab;System.out.println(a);}}这段代码的执行结果是什么&#xff1f;&#xff1f;2. 执行…

程序代码初学者_初学者:如何使用热键在Windows中启动任何程序

程序代码初学者Assigning shortcut keys to launch programs in Windows is probably one of the oldest geek tricks in the book, but in true geek fashion we are going to show you how to do it in Windows 8. 分配快捷键以在Windows中启动程序可能是本书中最古老的怪胎技…

stevedore——启用方式

2019独角兽企业重金招聘Python工程师标准>>> setuptools维护的入口点注册表列出了可用的插件&#xff0c;但是并没有为最终用户提供使用或启用的方法。 下面将描述用于管理要使用的扩展集的公共模式。 通过安装方式启用 对于许多应用程序&#xff0c;仅仅安装一个扩…

java 重置定时器_可重置Java定时器

我想有一个java.utils.Timer与一个可重置时间在java.I需要设置一次off事件发生在X秒。如果在创建定时器的时间和X秒之间没有发生任何事情&#xff0c;则事件会正常发生。然而&#xff0c;如果在X秒之前&#xff0c;我决定该事件应该发生在Y秒后&#xff0c;然后我想要能够告诉定…