我们都读过基准测试,知道事实--基于事件的异步网络服务器比它们的线程化服务器更快。想想lighttpd或Zeus与Apache或IIS。为什么会这样呢?
发布于 2008-11-14 13:57:41
我认为基于事件和基于线程不是问题--它是一个非阻塞的多路复用I/O,可选套接字,解决方案和线程池解决方案。
在第一种情况下,您将处理传入的所有输入,而不管使用它的是什么-因此在读取上没有阻塞-单个“侦听器”。单个侦听器线程将数据传递给不同类型的工作线程,而不是每个连接对应一个。同样,在写入任何数据时都不会阻塞-因此数据处理程序可以单独运行它。因为这个解决方案主要是IO读/写,所以它不会占用太多的CPU时间-因此您的应用程序可以利用这些时间来做它想做的任何事情。
在线程池解决方案中,您有单独的线程处理每个连接,因此它们必须共享上下文切换的时间-每个线程都“监听”。在此解决方案中,CPU + IO操作位于同一线程中-获得一个时间片-因此您最终只能等待每个线程的IO操作完成(阻塞),这通常可以在不占用CPU时间的情况下完成。
谷歌非阻塞IO获取更多细节-你也可以找到一些与线程池的比较。
(如果有人能澄清这几点,请随意)
发布于 2012-06-30 03:05:50
事件驱动的应用程序本身并不快。
来自Why Events Are a Bad Idea (for High-Concurrency Servers)
We examine the claimed strengths of events over threads and show that the
weaknesses of threads are artifacts of specific threading implementations
and not inherent to the threading paradigm. As evidence, we present a
user-level thread package that scales to 100,000 threads and achieves
excellent performance in a web server.这是在2003年。当然,从那时起,现代操作系统上的线程化状态已经有所改善。
编写基于事件的服务器的核心意味着在您的代码中重新发明协作多任务(Windows3.1风格),很可能是在已经支持适当的抢占式多任务的操作系统上,并且没有透明上下文切换的好处。这意味着您必须管理堆上的状态,这些状态通常由指令指针隐含或存储在堆栈变量中。(如果您的语言中有闭包,那么闭包可以极大地减轻这种痛苦。尝试用C语言做这件事就没那么有趣了。)
这也意味着您获得了协作多任务所暗示的所有注意事项。如果您的某个事件处理程序由于任何原因而需要一段时间才能运行,它就会停止该事件线程。完全不相关的请求延迟。为了避免这种情况,即使是冗长的CPU操作也必须发送到其他地方。当您谈论高并发服务器的核心时,“冗长的操作”是一个相对的术语,对于预计每秒处理100,000个请求的服务器来说,大约是微秒级。我希望虚拟内存系统永远不会为你从磁盘中取出页面!
从基于事件的体系结构中获得良好的性能可能很棘手,特别是当您考虑延迟而不仅仅是吞吐量时。(当然,在使用线程时也会犯很多错误。并发性仍然很难。)
对于新服务器应用程序的作者来说,有几个重要的问题:
发布于 2008-11-14 14:05:15
这实际上取决于您在做什么;基于事件的编程对于重要的应用程序来说肯定很棘手。作为一个web服务器确实是一个非常微不足道的问题,而且事件驱动和线程模型在现代操作系统上都能很好地工作。
在事件模型中正确地开发更复杂的服务器应用程序通常是相当棘手的--线程应用程序更容易编写。这可能是决定因素,而不是性能。
https://stackoverflow.com/questions/290128
复制相似问题