我有一个客户端服务器项目,并正在寻找更好的方式来处理来自客户端的请求。有人建议异步模式比同步模式和线程池模式更好。
我的问题是为什么?在异步模式中有缺点吗?处理客户请求时,为什么异步模式比同步模式好?
回答
是的,异步请求通常可以在不花费线程的情况下处理。操作系统对它们有特殊的支持,如重叠的I/O和完成端口等功能。他们实际上做的是利用内核线程的代价,无论如何,因为驱动程序需要能够处理来自多个用户模式程序的多个请求。 .NET框架很容易利用BeginXxx()方法中的优势。
使用线程池线程也很便宜,但是您需要遵守线程池调度程序的行为。这不像启动更多的TP线程那么多核心。 TP线程不应该用于代码,可以保持阻塞一段时间,非常典型的CS任务,如建立连接。
异步代码中的错误处理非常困难。当EndXxxx()方法引发异常时,通常情况下只有很少的上下文。它发生在一个回调线程上,离主逻辑很远。好吧,当你可以耸耸肩“没有发生,让我们记录下来”,当程序的状态取决于它时,总体情况和红色。在后一种情况下总是选择同步模式。
同步操作的一个缺点是IMO不能中断它们 - 例如,当你的服务器应用程序调用的同步方法为waitForConnection()和无客户端连接,你不能停下来等待...
例如尝试看看这个What is a good way to shutdown Threads blocked on NamedPipeServer#WaitForConnection?
在您对执手锁同步服务器当访问你的数据结构时(如果有更新),这需要时间和代码(并且是难以发现错误的来源)。在许多实现中(例如,用于堆栈分配)也具有许多(例如数千)线程带来了技术问题,并且如果服务器是IO限制,那些线程几乎全部正在休眠(等待网络)并且正在浪费存储器。在一个线程中使用异步模型,您可以忽略锁定问题(这意味着您的处理速度尽可能快),并且仅使用客户端实际需要的内存(只有一个堆栈)。
但是现在多核机器很常见,所以部分优势就会丢失(因为如果修改共享数据结构就必须锁定)。在N个异步服务器前面使用平衡器可能会获得最佳效率,其中N是您的环境的最佳线程数。
异步方法的坏处在于,根据您的工具,代码可能非常难看并且难以理解,如果计算不是微不足道的,并且错误地处理进入无限循环,则整个异步服务器将无响应(所以应该添加一个看门狗)。
异步并不解决锁定问题。您可以通过不同线程上的多个回调重新输入异步回调。使用异步模型时,您仍然需要保护任何共享状态。 – heavyd 2010-07-01 22:14:27
使用抢先式多线程编码正确锁定的问题是切换是“不可见的”,并且可能随时发生。 异步实现中的切换点是固定的,通常是绝对明显的。由于确定性,调试也更简单。 尽管仍然可能存在某种形式的“逻辑”锁定,但在我看来,与在共享数据更新方法中锁定权限的困难相比,没有什么可比的。 – 6502 2010-07-01 22:35:59
@heavyd:重新阅读您的评论在我看来,术语存在问题。我说过使用单线程异步实现,你可以忘记锁定问题......(这意味着关于并发访问的物理锁定,而不是自动机的状态改变之间的逻辑锁定,当然这是强制的),并且如果异步没有加上单线程,那么这个优点就失去了。 在您的评论中,您会讨论不同的主题,因此可能会对术语产生误解。 – 6502 2010-07-02 06:38:00
您不想阻止用户界面。通过异步操作,您可以在等待服务器响应时执行其他操作。
异步模式让您在同步模式让您等待时继续处理。
简单和简短的答案,但足够的解释。 感谢@Brian – 2015-08-12 06:51:05
用汉斯的回答“标记”:I/O操作与线程的独立性允许更显着的缩放;成千上万的未完成的请求是可能的,这是无法使用线程完成的。
另外,当你启动considering the complexities of error handling in protocol design时,事实证明异步方法的复杂程度远远低于正确编写同步代码的复杂度。大多数同步套接字代码看起来更简单,但实际上包含微妙的错误。
如果双方发送的数据比读取的数据多,则异步方法对于防止死锁情况也很重要;有关更多讨论,请参阅this blog post。
如果您希望在线程安全封装器(具有更简单的错误处理)中实现异步I/O的可靠性优势和(大部分)性能优势,请考虑Nito.Async库。
- 1. BPEL:异步/同步模式
- 2. 在React中处理异步请求的最佳模式是什么?
- 3. 异步命令模式 - 异常处理
- 4. 如何启用请求异步模式?
- 5. 的SQLAlchemy +请求的异步模式
- 6. .net tcp客户端异步模式
- 7. 如何将异步设计模式转换为同步模式?
- 8. 木筏领导是否同步或异步处理客户端请求?
- 9. 同步模式
- 10. 处理同步变量的最佳设计模式是什么?
- 11. 为什么异步XMLHttpRequests优先于同步请求?
- 12. EmberJS:异步模式
- 13. 异步HTTP的好处有什么好处异步HTTP
- 14. F#异步Web请求,处理异常
- 15. 在NSOperation子类中发送多个请求:同步还是异步模式?
- 16. SVN使用什么同步模式?
- 17. Rails异步处理模型
- 18. 多个异步Web请求来处理同步场景
- 19. 在Silverlight环境中同步异步请求处理程序
- 20. 用于处理Angular中最新的异步请求响应的模式?
- 21. JAX-RS客户端API异步请求
- 22. 使用rails,redis和node.js进行异步请求处理的方式是什么?
- 23. 节点JS Express模块是否异步处理请求?
- 24. javascript - 为什么有同步和异步模块的规范?
- 25. 处理ASP.NET MVC中的异步请求
- 26. ASP.NET Web API 2处理异步请求
- 27. 异步和web请求处理
- 28. 处理许多异步请求
- 29. 如何处理多个异步请求?
- 30. Grails - Servlet 3.0异步请求处理
+1它们甚至比这更好:通常不需要内核线程(大多数驱动程序甚至没有线程)。 – 2010-07-01 22:30:09
+1 vrey有用的答案。深深的谢谢! – 2010-07-01 22:46:47