我有一個客戶端服務器項目,並正在尋找更好的方式來處理來自客戶端的請求。有人建議異步模式比同步模式和線程池模式更好。
我的問題是爲什麼?在異步模式中有缺點嗎?處理客戶請求時,爲什麼異步模式比同步模式好?
回答
是的,異步請求通常可以在不花費線程的情況下處理。操作系統對它們有特殊的支持,如重疊的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