2009-12-16 49 views
2

我正在用boost asio編寫一些代碼,使用異步tcp連接。我不得不承認我對此有些懷疑。所有這些都涉及併發性。這裏有一些:Asio異步和併發

  • 如果我開始在同一插座上的兩個或兩個以上ASYNC_WRITE無需等待第一個完成,會發生什麼?處理程序(和async_write)重疊還是asio提供序列化和同步?

    • 以上同樣的問題與async_connect和async_read。一般來說,從不同線程調用這些函數是安全的(我不是在談論使用不同的緩衝區,這是另一個問題......)。

回答

2

我從你的問題中假設你有一個io_service實例,並且你想從多個線程調用它的asyncwrite()。 asyncwrite()最終調用ioservice的post()方法,該方法依次獲取一個鎖並將這些位寫入工作隊列,確保這些位不會被交錯寫入。這些位最終會被寫出來,並且持有它們的底層數據結構(char數組或其他)必須保持有效,直到獲得表示寫入已完成的回調。如果您使用完全相同的回調函數作爲完成處理程序,則無法知道哪個寫入會導致該函數被調用,並且如果該函數執行的任何操作都不是線程安全的,則行爲可能未定義或不正確。處理這種情況的一種常見方式是建立一個結構體的實例,它是完成處理程序(只是重載()運算符):您可以設置結構的屬性來表示它對應的寫入,然後在完成處理程序被調用。

但是,如果沒有共享鎖,則無法控制哪個線程實際執行其asyncwrite方法。事實上,即使你啓動了兩個線程,並且有一個線程立即調用asyncwrite並讓另一個線程休眠一個小時然後調用asyncwrite,但您仍然不確定操作系統不會愚蠢地調度線程並執行第二個線程先打電話。 (該例子是病態的,但該點是普遍有效的。)

同樣的情況適用於asyncreads。您當然可以交叉調用(即在調用完成處理程序之前執行一個asyncread和另一個asyncread,然後執行另一個),但不能保證按照您打算的順序執行該命令,而無需使用某些外部手段來確保這一點。

0

如果在同一插座上啓動兩個異步操作,他們可以發生在任何順序。只要他們使用不同的緩衝區,它是「安全的」,因爲它不會崩潰,但這種行爲幾乎從來都不是你想要的。