您的位置:首页 > 其它

使用多线程还是用IO复用select/epoll?

2013-03-23 13:27 387 查看
知乎

知乎搜索
搜索

提问

首页

话题

发现

注册知乎
登录

新浪微博注册 邮箱注册
知乎是一个真实的问答社区,在这里分享知识、经验和见解,感受最好的讨论体验,发现更大的世界。

网络编程Linuxepoll多线程


使用多线程还是用IO复用select/epoll?

每分钟有2K用户访问,服务器端处理请求选择用多线程(每个用户一个线程),还是用I/O复用?

3 条评论 分享

按票数排序


6 个回答

赞同
反对,不会显示你的姓名




蓝形参,皈依Node.js

22 票,来自 饶正锋赵磊李浩 更多

多线程模型适用于处理短连接,且连接的打开关闭非常频繁的情形,但不适合处理长连接。多线程模型默认情况下,(在Linux)每个线程会开8M的栈空间,再TCP长连接的情况下,2000/分钟的请求,几乎可以假定有上万甚至十几万的并发连接,假定有10000个连接,开这么多个线程需要10000*8M=80G的内存空间!即使调整每个线程的栈空间,也很难满足更多的需求。甚至攻击者可以利用这一点发动DDoS,只要一个连接连上服务器什么也不做,就能吃掉服务器几M的内存,这不同于多进程模型,线程间内存无法共享,因为所有线程处在同一个地址空间中。内存是多线程模型的软肋。
在UNIX平台下多进程模型擅长处理并发长连接,但却不适用于连接频繁产生和关闭的情形。Windows平台忽略此项。 同样的连接需要的内存数量并不比多线程模型少,但是得益于操作系统虚拟内存的Copy on Write机制,fork产生的进程和父进程共享了很大一部分物理内存。但是多进程模型在执行效率上太低,接受一个连接需要几百个时钟周期,产生一个进程 可能消耗几万个CPU时钟周期,两者的开销不成比例。而且由于每个进程的地址空间是独立的,如果需要进行进程间通信的话,只能使用IPC进行进程间通
信,而不能直接对内存进行访问。在CPU能力不足的情况下同样容易遭受DDos,攻击者只需要连上服务器,然后立刻关闭连接,服务端则需要打开一个进程再关闭。

同时需要保持很多的长连接,而且连接的开关很频繁,最高效的模型是非阻塞、异步IO模型。而且不要用select/poll,这两个API的有着O(N)的时间复杂度。在Linux用epoll,BSD用kqueue,Windows用IOCP,或者用libevent封装的统一接口(对于不同平台libevent实现时采用各个平台特有的API),这些平台特有的API时间复杂度为O(1)。 然而在非阻塞,异步I/O模型下的编程是非常痛苦的。由于I/O操作不再阻塞,报文的解析需要小心翼翼,并且需要亲自管理维护每个链接的状态。并且为了充分利用CPU,还应结合线程池,避免在轮询线程中处理业务逻辑。

但这种模型的效率是极高的。以知名的http服务器nginx为例,可以轻松应付上千万的空连接+少量活动链接,每个连接连接仅需要几K的内核缓冲区,想要应付更多的空连接,只需简单的增加内存(数据来源为淘宝一位工程师的一次技术讲座,并未实测)。这使得DDoS攻击者的成本大大增加,这种模型攻击者只能将服务器的带宽全部占用,才能达到目的,而两方的投入是不成比例的。



2012-04-07
2 条评论

赞同
反对,不会显示你的姓名




dccmx,IT、互联网、搞技术的

4 票,来自 Feisky安江泽沈沉 更多

钟有2K?差点看成每秒钟。

这2K个用户是长连接呢还是短连接呢?如果是短连接,或者连接后通信不频繁的话,线程(池)就可以,如果一直是2k的并发,那还是异步(epoll)靠谱点。再高就要异步加并行(多线程/多进程)了。

2012-03-11
添加评论

赞同
反对,不会显示你的姓名




狼大人,Ade,
Ubuntu "Desktop"

1 票,来自 陈硕

能够用 I/O 复用和异步或无阻塞 I/O 代替多线程基本肯定能减轻系统压力,但如果每个客户响应过程耗时较长(如涉及阻塞 I/O、调用外部 API 等)则有时候多线程也是必须的。

2012-03-11
添加评论

赞同
反对,不会显示你的姓名




孙永跃,基础架构与算法,分布式存储与网络,开放…

1 票,来自 Jonas Yang

2k个很少,业务若不复杂就随便选一个。量大一般会结合使用。

2012-04-05
添加评论

赞同
反对,不会显示你的姓名




谢立超,IT工程师,从事分布式系统研发。

二者结合

2012-03-11
添加评论

赞同
反对,不会显示你的姓名




汪露林,cumter,
coder

服务器几个cpu(核)?

2012-03-11
添加评论

我来回答这个问题







写回答…

我要回答

相关问题

Linux中进程和线程的开销基本一样啊,为什么还要多线程呢? 7
个回答
多线程学习怎样入门? 4 个回答
为什么 MySQL 使用多线程,而 Oracle 和 PostgreSQL 使用多进程? 4
个回答
在处理多线程方面,哪一种语言处理的比较好? 2 个回答
java虚拟机,多线程,网络学好了对于找工作帮助大吗? 3
个回答





知乎阅读发现
知乎协议 • © 2013 知乎
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: