2011-03-12 118 views
18

據我所知,同步和異步操作之間的主要區別。即write()read() vs async_write()async_read()是前者,直到操作完成後才返回 - 或錯誤 - 和最後一個,立即返回。需要關於同步和異步操作的一些說明

由於異步操作由io_service.run()控制,直到受控操作完成才完成。在我看來,在連續的操作中所涉及的與協議,如POP3 TCP/IP連接,其中操作的順序,如:

C: <connect> 
S: Ok. 
C: User... 
S: Ok. 
C: Password 
S: Ok. 
C: Command 
S: answer 
C: Command 
S: answer 
... 
C: bye 
S: <close> 

同步/異步運營商之間的差別並不太大感。

當然,在這兩個操作中,程序流程總會有一定的風險 - 在某些情況下 - 使用定時器 - ,但我想知道更多關於此問題的授權意見。

我必須承認,這個問題是相當不明確的,但我想聽聽什麼時候使用其中一個的建議。在使用MS Visual Studio進行調試時,我遇到了一些問題,這些問題涉及到我正在使用的POP3客戶端中的異步SSL操作,有時候認爲在這種情況下使用異步也許是個壞主意。

+4

+1甚至沒有接近不明確的問題。異步編程很難,不要羞於對它提出疑問。 – 2011-03-13 14:11:20

回答

3

我想同步/異步的選擇是非常特定於應用程序的。我同意異步範例可以使代碼和調試更加複雜,但它確實有其好處。

爲了說明,我們使用異步IO從同步IO切換到boost asio的主要原因在於,在我們的應用程序中,阻止IO僅僅是一種選擇,我們有一個多媒體流媒體服務器,客戶編碼後。問題在於網絡問題導致整個捕獲 - 編碼 - 交付流水線被有效阻塞(例如,如果與單個客戶端的連接失敗)。總結一下,在我的(有關異步IO的經驗)中,它可以用於在等待IO完成時需要完成其他工作的情況(例如爲其他客戶端提供服務等) 。在系統或場景中,如果您必須等待IO的結果繼續,那麼僅使用同步IO就簡單多了。

在雙工通信系統中(例如更復雜的協議,例如SIP和RTSP,客戶端和服務器都可以發送請求),這也是有意義的。自從我處理POP以來,這已經有一段時間了,但在您的示例中進行了簡單交換之後,異步IO可能會被視爲過度消耗。只有當我確定同步IO不足以滿足我的要求時,我纔會切換到異步IO。

WRT到boost asio文檔,我發現最好的方法是完成這個例子。此外,您可能想要查看的鏈接是http://en.highscore.de/cpp/boost/index.html它對增強asio有非常好的一章。另外Chris Kohlhoff's (author of asio) blog有一些非常優秀的文章值得一試。

+0

感謝您的意見。你的話對我來說是有道理的,而且到目前爲止還沒有人知道這本高分榜。 – 2011-03-12 21:14:58

31

Boost.Asio documentation對解釋這兩個概念真的很出色。作爲Ralf mentioned,克里斯還有一個很棒的博客,描述異步概念。解釋超時工作方式的parking meter示例與bind illustrated示例一樣特別有趣。

首先,考慮同步連接操作:

synchronous connect

控制流程相當簡單在這裏,你的程序調用API的一些(1)連接套接字。 API使用I/O服務(2)在操作系統(3)中執行操作。一旦此操作完成(4和5),控制器會立即返回到您的程序(6),並顯示成功或失敗的指示。

中類似的異步操作具有完全不同的控制流程:

asynchronous connect

在這裏,你的應用發起使用相同的I/O服務(2)的操作(1),但該控制流是倒。操作完成後,I/O服務會通過完成處理程序通知您的程序。步驟3到操作完成之間的時間完全包含在同步案例的連接操作中。

對於大多數程序員來說,您可以看到同步案例自然更容易掌握,因爲它代表了傳統的控制流範式。異步操作使用的反向控制流很難理解,它經常會迫使你的程序將操作分解爲邏輯移位的方法starthandle。但是,一旦你對這個控制流程有了基本的瞭解,你就會意識到這個概念真的有多強大。異步編程的一些優點是:

  • 將線程從併發中分離出來。執行長時間運行的操作,對於同步情況,您通常會創建單獨的線程來處理操作,以防止應用程序的GUI無響應。這個概念在小範圍內運行良好,但很快就會在一些線程中崩潰。

  • 性能提高。線程每連接設計根本不會縮放。請參閱C10K problem

  • 構圖(或鏈接)。更高級別的操作可以由多個完成處理程序組成。考慮傳輸JPEG圖像,該協議可能規定前40個字節包括描述圖像大小,形狀或其他信息的標題。發送此標頭的第一個完成處理程序可以啓動第二個操作來發送圖像數據。更高級別的操作sendImage()不需要知道或關心用於實現數據傳輸的方法鏈接。

  • 超時和取消能力。有特定於平臺的方式來超時長時間運行(例如:SO_RCVTIMEOSO_SNDTIMEO)。使用異步操作可以使用deadline_timer取消所有支持的平臺上的長時間運行操作。


當然,在這兩個操作有 永諾的程序流程 無限期停止一些 circunstance -there使用 timers-的風險,但我想知道一些 更多關於此 事宜的授權意見。

我個人使用Asio的經驗源於可擴展性方面。編寫supercomputers的軟件需要在處理有限的資源(如內存,線程,套接字等)時進行相當的處理。使用每個線程連接200萬個同時進行的操作是一種在到達時已死亡的設計。

+2

儘管使用它的時間已經過去,互聯網仍然不時地對我「保持一絲」魔力「。在這種情況下,有免費的好老師的奇蹟。謝謝。 – 2011-03-13 18:59:46

+0

我總是發現難以理解短語「倒轉控制流」。所以你可以在這個上下文中詳細說明「倒置」這個詞*「你的應用程序使用相同的I/O服務(2)**啓動操作(1),但是控制流被反轉**。儘管我非常瞭解控制流,但我無法將「反轉」一詞與異步情況中發生的情況聯繫起來。對我而言,感覺就像選擇一個隨機單詞來給控制流*一個名字或標籤。 – Nawaz 2016-08-24 03:55:47

+0

**反向控制流**表示框架或庫(此答案中的Asio)回調到程序中,這些是異步操作完成時的回調。與程序直接調用框架或庫的典型過程編程相比,ex:同步send()操作在完成時返回控制權。 – 2016-08-29 04:59:40

0

一個簡單的回答是:(引自here幾乎不做修改)

同步客戶一切都發生在串行。如果你發送一個命令,它會排隊在前一個命令後面,直到它們完成。通常是單線程應用程序。

在ASync中,所有事情都同時發生。通常會同時承擔多項任務的多線程應用程序。

+2

Javascript是單線程和異步...和美妙的。我不認爲異步連接到多線程 – 2016-01-11 12:13:37

+0

向下投票:我不認爲這是正確的。處理多個網絡連接的一種方法是爲每個連接建立一個線程或進程,並且每個連接都在自己的線程/進程中運行,所有的I/O都是同步的。在異步I/O設計中,您可以擁有任意數量的線程或進程,即使是單個進程也可以處理多個連接。事實上,我猜測發明異步I/O機制的一個主要動機是擺脫編寫(過度)多線程代碼的需求,這些代碼在某些平臺上帶來了自己的可伸縮性問題。 – FooF 2016-03-28 14:01:48