2016-06-13 23 views
0

關於這個帖子: Why do I need strand per connection when using boost::asio?使用升壓異步API的多線程

我專注於這個聲明對於異步調用: 「不過,這是不是安全的多線程撥打電話同時」

此示例: http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp11/chat/chat_client.cpp

如果我指的是主要爲「線程1」,並且產生的線程T作爲「線程2」,則好像線程1是調用ASYNC_WRITE(假設沒有write_in_progress),而線程2是調用ASY nc_read。我錯過了什麼?

+0

可能是io_service線程(t)免於此規則。 – Chris

回答

1

在官方chat examplechat_client::write()推遲通過io_service::post()工作的io_service,這將:

  • 要求,即io_service通過當前調用線程執行指定的處理程序poll()poll_one()run(),或run_one()功能io_service
  • 不允許在調用函數內調用給定的處理程序(例如,chat_client::write()

由於只有一個線程正在運行io_service,並且所有套接字的讀取,寫入和關閉操作僅從發佈到io_service的處理程序啓動,所以該程序滿足socket的線程安全要求。

class chat_client 
{ 
    void write(const chat_message& msg) 
    { 
    // The nullary function `handler` is created, but not invoked within 
    // the calling function. `msg` is captured by value, allowing `handler` 
    // to append a valid `msg` object to `write_msgs_`. 
    auto handler = [this, msg]() 
     { 
     bool write_in_progress = !write_msgs_.empty(); 
     write_msgs_.push_back(msg); 
     if (!write_in_progress) 
     { 
      do_write(); 
     } 
     }; 

    // Request that `handler` be invoked within the `io_service`. 
    io_service_.post(handler); 
    } 
}; 
+0

有趣。那io_service :: post絕對是我在看的聊天示例(v1.55)和最新的聊天示例(v1.61)之間的區別。所以,看起來好像有人注意到和我一樣的東西,並修正它。我從現在開始堅持最新版本。 – Chris

+0

@Chris也許這個例子不是一個正式的例子嗎? 'io_service.post'位於[1.55 C++ 11聊天客戶端](https://github.com/boostorg/asio/blob/boost-1.55.0/example/cpp11/chat/chat_client.cpp#L35)並且自從Asio被Boost接受以來一直用於該示例(參見[1.35聊天示例](http://www.boost.org/doc/libs/1_35_0/doc/html/booster_asio/example/chat/chat_client.cpp ))。 –

+0

我的鏈接轉到boost.org ......據我所知,這是官方的。它在谷歌搜索中也顯示出很高,但我不記得我搜索的是什麼。也許你說這個文件存在於他們的服務器上,但不是1.55官方文檔的一部分。可能。它沒有頁面右下方的「home」和箭頭按鈕,就像我在其他boost.org文檔中看到的那樣。如果你看看我鏈接的頁面... io_service :: post缺失,然後點擊頂部的鏈接將你帶到「此頁面的最新版本」,並顯示io_service :: post。奇。 – Chris