epoll函数

Redis 单线程却能支撑高并发 - 简书 https://www.jianshu.com/p/2d293482f272

时间秒杀一切 提交于 2020-01-09 18:14:33
小结: 1、 在 I/O 多路复用模型中,最重要的函数调用就是 select,该方法的能够同时监控多个文件描述符的可读可写情况; 2、 Redis 服务采用 Reactor 的方式来实现文件事件处理器(每一个网络连接其实都对应一个文件描述符); 3、 虽然整个文件事件处理器是在单线程上运行的,但是通过 I/O 多路复用模块的引入,实现了同时对多个 FD 读写的监控,提高了网络通信模型的性能,同时也可以保证整个 Redis 服务实现的简单 4、 Redis 会优先选择时间复杂度为 O(1) 的 I/O 多路复用函数作为底层实现,包括 Solaries 10 中的 evport、Linux 中的 epoll 和 macOS/FreeBSD 中的 kqueue,上述的这些函数都使用了内核内部的结构,并且能够服务几十万的文件描述符。 但是如果当前编译环境没有上述函数,就会选择 select 作为备选方案,由于其在使用时会扫描全部监听的描述符,所以其时间复杂度较差 O(n),并且只能同时服务 1024 个文件描述符,所以一般并不会以 select 作为第一方案使用。 https://mp.weixin.qq.com/s/ySG2Qtitr6b8Zcb-SAMnGQ Redis 和 I/O 多路复用 https://draveness.me/redis-io-multiplexing

网络IO模型

拈花ヽ惹草 提交于 2020-01-02 09:21:16
在介绍网络IO模型,我们先来看一下同步和异步,以及阻塞和非阻塞的概念。 同步和异步关注的是结果消息的通信机制 同步:同步的意思就是调用方需要主动等待结果的返回 异步:异步的意思就是不需要主动等待结果的返回,而是通过其他手段比如,状态通知,回调函数等。 阻塞和非阻塞主要关注的是等待结果返回调用方的状态 阻塞:是指结果返回之前,当前线程被挂起,不做任何事 非阻塞:是指结果在返回之前,线程可以做一些其他事,不会被挂起。 然后我们就来了解一些基本的网络IO模型 阻塞I/O(blocking I/O) 非阻塞I/O (nonblocking I/O) I/O复用(select 、poll和epoll) (I/O multiplexing) 信号驱动I/O (signal driven I/O (SIGIO)) 异步I/O (asynchronous I/O ) 阻塞I/O模型 应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好。 如果数据没有准备好,一直等待,知道数据准备好了,从内核拷贝到用户空间,IO函数返回成功指示。 当调用recvfrom()函数时,系统首先查是否有准备好的数据。如果数据没有准备好,那么系统就处于等待状态。当数据准备好后,将数据从系统缓冲区复制到用户空间,然后该函数返回。在套接应用程序中,当调用recvfrom()函数时,未必用户空间就已经存在数据

并发编程(IO多路复用)

被刻印的时光 ゝ 提交于 2019-12-31 23:29:37
转: https://www.cnblogs.com/cainingning/p/9556642.html 阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 异步IO(Asynchronous I/O) 六 IO模型比较分析 七 selectors模块 IO模型介绍   为了更好地了解IO模型,我们需要事先回顾下:同步、异步、阻塞、非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答案都可能不同,比如wiki,就认为asynchronous IO和non-blocking IO是一个东西。这其实是因为不同的人的知识背景不同,并且在讨论这个问题的时候上下文(context)也不相同。所以,为了更好的回答这个问题,我先限定一下本文的上下文。 本文讨论的背景是Linux环境下的network IO。本文最重要的参考文献是Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking ”,6

elect、poll、epoll优缺点

僤鯓⒐⒋嵵緔 提交于 2019-12-31 11:04:51
select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作 。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的 ,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。 select的几大缺点: (1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大 (2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大 (3)select支持的文件描述符数量太小了,默认是1024 2 poll实现   poll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其他的都差不多。 select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。但是解决了select的文件描述符的最大上线数 3、epoll   epoll既然是对select和poll的改进,就应该能避免上述的三个缺点。那epoll都是怎么解决的呢?在此之前

epoll、多线程模型

我怕爱的太早我们不能终老 提交于 2019-12-29 14:50:12
如何切换epoll event_loop.c 文件的 event_loop_init_with_name 函数是关键,通过宏 EPOLL_ENABLE 来决定是使用 epoll 还是 poll 的。 struct event_loop * event_loop_init_with_name ( char * thread_name ) { . . . # ifdef EPOLL_ENABLE yolanda_msgx ( "set epoll as dispatcher, %s" , eventLoop -> thread_name ) ; eventLoop -> eventDispatcher = & epoll_dispatcher ; # else yolanda_msgx ( "set poll as dispatcher, %s" , eventLoop -> thread_name ) ; eventLoop -> eventDispatcher = & poll_dispatcher ; # endif eventLoop -> event_dispatcher_data = eventLoop -> eventDispatcher -> init ( eventLoop ) ; . . . } 根目录下的 CMakeLists.txt 文件里,引入

poll, select & epoll 原理比较分析

 ̄綄美尐妖づ 提交于 2019-12-26 23:46:52
因为需要了解底层设备访问的原理,所以惯用高层应用语言的我,需要了解一下Linux的设备访问机制,尤其是处理一组非阻塞IO的原理方法,标准的术语好像是叫多路复用。以下文章部分句子有引用之处,恕没有一一指出出处。 对于接触过Linux内核或设备驱动开发的读者,一定清楚poll和select系统调用,以及从2.5版本引入的epoll机制(epoll机制包含三个系统调用)。网上关于它们的文章,有说用法的,甚为详细,更有分析源代码的,又比较深入,且枝节颇多。经过几篇文章的阅读,我把觉得比较核心的东西写下来吧。我的用意是尽可能以简单的概念,比对他们三者的异同。 几经查找我才确定下来,poll和select应该被归类为这样的系统调用,它们可以阻塞地同时探测一组支持非阻塞的IO设备,是否有事件发生(如可读,可写,有高优先级的错误输出,出现错误等等),直至某一个设备触发了事件或者超过了指定的等待时间——也就是它们的职责不是做IO,而是帮助调用者寻找当前就绪的设备。同类型的产品是Windows的IOCP,它也是处理多路复用,只是把IO和探测封装在了一起了。 准备的知识有两点:1、fd;2、op->poll。 在Linux里面,设备都被抽象为文件,一系列的设备文件就有自己独立的虚拟文件系统,所以,设备在系统调用参数中的表示就是file description。fd其实就是一个整数(特别地,标准输入,输出

select、poll和epoll的比较

蓝咒 提交于 2019-12-24 07:25:40
一、select机制   在linux下网络通信中,经常用到select机制,这是一种异步通信的实现方式,select中提供一fd_set的数据结果, 实际上是一个long类型的数组 , 每一个数组元素都能与一打开的文件句柄建立联系,通常这个句柄并不局限于网络通信中的socket句柄,还包括其他文件、命名管道或设备句柄等。 当程序中调用select()时,由内核 根据IO状态修改fd_set的内容,由此来通知执select()的进程哪一Socket或文件可读或者可写。    select的本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是:   1、单个进程可监视的fd数量受到了限制,在32位机器上,他所能管理的fd数量最大为1024。   2、 需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大。   3、 对socket进行扫描时是线性扫描,当socket文件描述符数量变多时,大量的时间是被白白浪费掉的。 二、poll机制   poll是 Linux中的字符设备驱动 中有一个函数,Linux 2.5.44版本后已经被epoll所取代。 poll机制是用在某些Unix系统中,使用poll()函数用于执行与select()函数同等功能的函数。    poll本质上和select没有区别

select、poll、epoll之间的区别总结[整理]

狂风中的少年 提交于 2019-12-24 07:25:06
 select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。 但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的 ,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。关于这三种IO多路复用的用法,前面三篇总结写的很清楚,并用服务器回射echo程序进行了测试。连接如下所示: select: http://www.cnblogs.com/Anker/archive/2013/08/14/3258674.html poll: http://www.cnblogs.com/Anker/archive/2013/08/15/3261006.html epoll: http://www.cnblogs.com/Anker/archive/2013/08/17/3263780.html   今天对这三种IO多路复用进行对比,参考网上和书上面的资料,整理如下: 1、select实现 select的调用过程如下所示: (1)使用copy_from_user从用户空间拷贝fd_set到内核空间 (2)注册回调函数__pollwait (3)遍历所有fd

select、poll、epoll之间的区别总结[整理]

怎甘沉沦 提交于 2019-12-24 07:24:32
   select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。 但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的 ,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。 关于这三种IO多路复用的用法,前面三篇总结写的很清楚,并用服务器回射echo程序进行了测试。连接如下所示: select: http://www.cnblogs.com/Anker/archive/2013/08/14/3258674.html poll: http://www.cnblogs.com/Anker/archive/2013/08/15/3261006.html epoll: http://www.cnblogs.com/Anker/archive/2013/08/17/3263780.html   今天对这三种IO多路复用进行对比,参考网上和书上面的资料,整理如下: 1、select实现 select的调用过程如下所示: (1)使用copy_from_user从用户空间拷贝fd_set到内核空间 (2)注册回调函数__pollwait (3)遍历所有fd

Epoll使用实例

喜欢而已 提交于 2019-12-24 03:12:27
Epoll使用实例 函数详情 atoi 将字符串转化为int int atoi (const char * str) atol 将字符串转化为long long int atol ( const char * str ) 扩展实例 Server_epoll.cc #include <iostream> #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> //#include <memory.h> //menset #include <sys/epoll.h> #include <fcntl.h> #define SOCKET_PORT 9999 #define EPOLL_SIZE 10 int main(int argc, char *argv[]) { int server_fd; int client_fd; int epfd; struct sockaddr_in addr; memset(&addr,0,sizeof(addr)); addr.sin_family = AF_INET; if (argc == 2){