多线程 or I/O复用select/epoll

1:多线程模型适用于处理短连接,且连接的打开关闭非常频繁的情形,但不适合处理长连接。
线程模型默认情况下,在Linux下每个线程会开8M的栈空间,在TCP长连接的情况下,以2000/分钟的请求为例,几乎可以假定有上万甚至十几万的并发连接,假定有10000个连接,开这么多个线程需要10000*8M=80G的内存空间!即使调整每个线程的栈空间,也很难满足更多的需求。甚至攻击者可以利用这一点发动DDoS,只要一个连接连上服务器什么也不做,就能吃掉服务器几M的内存,这不同于多进程模型,线程间内存无法共享,因为所有线程处在同一个地址空间中。内存是多线程模型的软肋。

2:在UNIX平台下多进程模型擅长处理并发长连接,但却不适用于连接频繁产生和关闭的情形。
Windows平台忽略此项。 同样的连接需要的内存数量并不比多线程模型少,但是得益于操作系统虚拟内存的Copy on Write机制,fork产生的进程和父进程共享了很大一部分物理内存。但是多进程模型在执行效率上太低,接受一个连接需要几百个时钟周期,产生一个进程 可能消耗几万个CPU时钟周期,两者的开销不成比例。而且由于每个进程的地址空间是独立的,如果需要进行进程间通信的话,只能使用IPC进行进程间通 信,而不能直接对内存进行访问。在CPU能力不足的情况下同样容易遭受DDos,攻击者只需要连上服务器,然后立刻关闭连接,服务端则需要打开一个进程再关闭。

3:同时需要保持很多的长连接,而且连接的开关很频繁,最高效的模型是非阻塞、异步IO模型。
不要用select/poll,这两个API的有着O(logN)的时间复杂度。在Linux用epoll,BSD用kqueue,Windows用IOCP,或者用libevent封装的统一接口(对于不同平台libevent实现时采用各个平台特有的API),这些平台特有的API时间复杂度为O(1).然而在非阻塞,异步I/O模型下的编程是非常痛苦的。由于I/O操作不再阻塞,报文的解析需要小心翼翼,并且需要亲自管理维护每个链接的状态。并且为了充分利用CPU,还应结合线程池,避免在轮询线程中处理业务逻辑。但这种模型的效率是极高的。以知名的http服务器nginx为例,可以轻松应付上千万的空连接+少量活动链接,每个连接连接仅需要几K的内核缓冲区,想要应付更多的空连接,只需简单的增加内存(数据来源为淘宝一位工程师的一次技术讲座,并未实测)。这使得DDoS攻击者的成本大大增加,这种模型攻击者只能将服务器的带宽全部占用,才能达到目的,而两方的投入是不成比例的。

来自为知笔记(Wiz)

时间: 2024-08-21 17:10:09

多线程 or I/O复用select/epoll的相关文章

Linux下的I/O复用与epoll详解

前言 I/O多路复用有很多种实现.在linux上,2.4内核前主要是select和poll,自Linux 2.6内核正式引入epoll以来,epoll已经成为了目前实现高性能网络服务器的必备技术.尽管他们的使用方法不尽相同,但是本质上却没有什么区别.本文将重点探讨将放在EPOLL的实现与使用详解. 为什么会是EPOLL select的缺陷 高并发的核心解决方案是1个线程处理所有连接的“等待消息准备好”,这一点上epoll和select是无争议的.但select预估错误了一件事,当数十万并发连接存

select,epoll,poll比较

select,poll,epoll简介 select select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理.这样所带来的缺点是: 1 单个进程可监视的fd数量被限制 2 需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大 3 对socket进行扫描时是线性扫描 poll poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历

UNPv1第六章:IO复用select&poll

有些进程需要一种预先告知内核的能力,使得内核一旦发现进程指定的一个或多个I/O条件就绪(也就是说输入已准备好被读取,或者描述符已能承受更多的输出),他就通知进程,这个能力称为I/O复用 1.IO模型 5种基本I/O模型 阻塞式I/O 非阻塞式I/O I/O复用(select和poll) 信号驱动式I/O(SIGIO) 异步I/O 一个输入操作通常包括两个不同的阶段 (1)等待数据准备 (2)从内核向进程复制数据 对于一个套接口上的输入操作,第一步一般是等待数据到达网络,当分组到达时,它被拷贝到内

五种网络IO模型以及多路复用IO中select/epoll对比

下面都是以网络读数据为例 [2阶段网络IO] 第一阶段:等待数据 wait for data 第二阶段:从内核复制数据到用户 copy data from kernel to user 下面是5种网络IO模型 [阻塞blocking IO] 两阶段全程阻塞 recvfrom -> [syscall -> wait -> copy ->] return OK [非阻塞nonblocking IO] 第一阶段是非阻塞的不断检查是否数据准备好,第二阶段阻塞读取数据 recvfrom -&

[Z] linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO

原文链接:http://blog.csdn.net/colzer/article/details/8169075 IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file descriptor(fd,文件描述符).而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符).描述符就是一个数字,指向内核中一个结构体(文件路径,数据

linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)

IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file descriptor(fd,文件描述符).而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符).描述符就是一个数字,指向内核中一个结构体(文件路径,数据区,等一些属性).那么我们的应用程序对文件的读写就通过对描述符的读写完成. linux将内存分为内核区,用户区.l

IO复用之——epoll

一. 关于epoll 对于IO复用模型,前面谈论过了关于select和poll函数的使用,select提供给用户一个关于存储事件的数据结构fd_set来统一监测等待事件的就绪,分为读.写和异常事件集:而poll则是用一个个的pollfd类型的结构体管理事件的文件描述符和事件所关心的events,并通过结构体里面的输出型参数revents来通知用户事件的就绪状态: 但是对于上述两种函数,都是需要用户遍历所有的事件集合来确定到底是哪一个或者是哪些事件已经就绪可以进行数据的处理了,因此当要处理等待的事

高性能网络服务器--I/O复用 select poll epoll_wait之间的区别

一.select 使用的集合的方式,最多只能监听1024个文件描述符,内部使用位操作,将相应的位置为1或者置为0,需要将可读.可写.异常的三类事件分开来用,内部使用轮询的方法,每次返回都需要将所有的套接字从内核到用户空间之间进行拷贝. 二.poll 比select稍微好一点,也是在指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪. 三.epoll_wait 把用户关心的文件描述符上事件放在内核里的一个事件表中从而无需像select和poll那样每次调用都要重复传入文件描述符集或者事件集.

从I/O复用谈epoll为什么高效

上一篇文章中,谈了一些网络编程的基本概念.在现实使用中,用的最多的就是I/O复用了,无非就是select,poll,epoll 很多人提到网络就说epoll,认为epoll效率是最高的.单纯的这么认为,其实有失偏颇.epoll固然高效,可是它是怎么做到高效的,它到底比select或poll优异在哪儿? 我们通过调用流程来简单分析下. 首先以select为例(poll类似),看下其调用过程 1.选择想要处理的套接字,通过接口FD_SET(fd, &set)加入到set中; 2.调用select(m