多路复用IO
## I/O 多路复用之select、poll、epoll详解 3个都是负责监控socket连接 # select,poll,epoll都是IO多路复用的机制 I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。 # select select(rlist, wlist, xlist, timeout=None) select 函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述副就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以 通过遍历fdset,来找到就绪的描述符 # 优点 select跨平台 # 缺点 1 单个进程能够监视的文件描述符的数量存在最大限制,默认1024个 2 对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低 select100个连接发出后,CPU返回时会告诉select100的其中一个有返回值,由select自己循环查找哪个有数据 ,那么99吃循环会浪费了 3 需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大 # poll 少用 pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式。同时,pollfd并没有最大数量限制(但是数量过大后性能也是会下降) # epoll (使用最多的)win不支持,nginx epoll是在2.6内核中提出的,是之前的select和poll的增强版本 相对于select和poll来说,epoll更加灵活,没有描述符限制 epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次 # 优点: 1 没有最大并发连接的限制 2 效率提升,不是轮询的方式,不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数; 3 内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销。 ## 综上,在选择select,poll,epoll时要根据具体的使用场合以及这三种方式的自身特点。 1、表面上看epoll的性能最好,但是在连接数少并且连接都十分活跃的情况下select和poll的性能可能比epoll好,毕竟epoll的通知机制需要很多函数回调。 2、select低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善 # 并发编程模型: 单进程模型:串行方式响应 多进程模型:prefork机制 一个进程响应一个用户请求,并发使用多进程实现 多线程模型:worker机制 一个进程生成多个线程,一个线程响应一个用户,并发使用多个线程,n进程 n×m线程 事情模型:event机制,一个线程直接响应多个用户请求,基于事件驱动的机制来维持多个用户请求 # prefork: 预先生成进程,一个请求用一个进程响应.优点:稳定可靠、执行效率高,任何一个进程的崩溃不会影响其它请求.缺点:在大并发的时候对服务器资源消耗严重. # worker: 基于线程的处理方式,一个进程生成多个线程,一个请求用一个线程响应.由于使用线程访问,多个线程共享同一个进程的资源,如果一个进程访问过某一个文件并且打开了,另一个线程访问就不用再次打开.优点:在高并发的情况下,对服务器的资源消耗相对prefork模型要小很多.缺点:执行效率、稳定性都不如prefork模型.linux不是个原生支持线程的操作系统,经测试发现worker模型在linux上面的综合表现不如prefork模型. # event: 基于事件驱动的处理模型,一个进程处理多个请求.前面两种模型在开启长连接的情况下都是保持一个整的进程或线程来等待客户端的请求,在高并发的情况下这种机制很快会耗光服务器的可用进程.event模型简单的来说就是把线程进行分工,采用专用的进程来监听套接字保持连接,因为监听套接字和保持TCP连接所需要的资源极小一个进程就可以处理大量的这种请求.需要注意的event模型是不能再https的访问下工作的. # apache: IO模型:多路复用select(Apache 2.2.9之前只支持select模型,2.2.9之后支持epoll模型) 工作模式:prefork/worker/event,prefork>worker>event
默认prtfork:就是使用select方式工作的,并发不能超过1024 master主进程 master生成子进程,由master来调度每个子进程负责响应客户请求 那么对用户来说每一个IO调用是发给master主进程的,因为只有一个80端口 那么master主进程要监控多个IO是否完成,所以master主进程向内核注册使用IO多路复用机制 让内核的系统调如select或poll负责监控哪一个IO请求完成,那么master就要调用一次select select返回哪一个IO请求完成和没完成,master主进程就循环返回结果知道了某个IO请求完成,那么就调用某子进程响应 # nginx: IO模型:多路复用epoll 工作模式:默认一个master进程,多个worker工作进程(少于CPU核心数) master\worker架构:一个master进程,可生成一个或多个work进程 master:加载配置文件,管理worker进程,平滑升级 worker:http服务,http代理,fastcgi代理
本文来自博客园,站在巨人的肩膀上,坚持开源精神,遵循开源协议:Apache Licene 2.0协议。
浙公网安备 33010602011771号