在 strands 的 boost asio檔案中,它說:
鏈可以是隱式的或顯式的,如以下替代方法所示:
- ...
- 如果存在與連接相關聯的單條異步操作鏈(例如,在 HTTP 等半雙工協議實作中),則不可能同時執行處理程式。這是一條隱含的鏈。
- ...
然而,在 boost beast 的多執行緒異步 http 服務器示例中,boost::asio::ip::tcp::acceptor每個服務器都明確地boost::asio::ip::tcp::socket獲得了自己的鏈(參見第373和425行)。據我所知,這不是必需的,因為所有這些物件只會在順序注冊/運行中被訪問。1確切地說,這些物件之一的新異步操作只會在在同一物件上注冊的結尾,使任何物件都可以在單個異步操作鏈中使用。2CompletionHandlerCompletionHandler
因此,我假設 - 盡管有多個執行緒同時運行 - 在這個例子中可以一起省略 strands 并且io_context可以直接用于調度任何異步操作。那是對的嗎?如果沒有,我錯過了哪些同步問題?我是否誤解了上述檔案中的陳述?
1:當然,兩個套接字或一個套接字和接受器可以同時使用,但由于使用了多個 stands,這在示例中也沒有被阻止。
2:不可否認,在當前處理程式實際完成之前CompletionHandler,在當前處理程式結束時注冊的CompletionHandler可能在另一個執行緒上啟動,即回傳。但我認為這不是一個有同步問題風險的情況。糾正我,如果我錯了。
uj5u.com熱心網友回復:
如果異步操作鏈創建了一個邏輯鏈,那么您通常不需要顯式鏈。
此外,如果執行背景關系僅從單個執行緒運行/輪詢,則所有異步操作都將在該隱式鏈上有效。
這些例子不止一個目的。
一方面。他們顯然保持簡單。自然會有最少數量的執行緒或簡單的操作鏈。
但是,這會導致示例過于簡單,與現實生活的關系太少。
因此,即使不是絕對需要,這些示例也經常顯示出良好的實踐或高級模式。有時(通常是 IME)這甚至會被明確地注釋掉。例如,在您非常鏈接的示例L277中:
// We need to be executing within a strand to perform async operations // on the I/O objects in this session. Although not strictly necessary // for single-threaded contexts, this example code is written to be // thread-safe by default. net::dispatch(stream_.get_executor(), beast::bind_front_handler( &session::do_read, shared_from_this()));
勵志例子
這使人們能夠解決他們的下一個重要任務。例如,假設您想從鏈接示例中添加stop()到類中。listener沒有鏈就沒有辦法安全地做到這一點。您需要在邏輯“鏈”acceptor.cancel() 內部“注入”一個呼叫,異步操作鏈包含async_accept. 但你不能,因為async_accept“邏輯上阻塞”了那個鏈。所以你實際上確實需要發布到一個明確的鏈:
void stop() {
post(acceptor_.get_executor(), [this] { acceptor_.cancel(); });
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/443099.html
下一篇:為什么我會遇到這個錯誤:在'arr'中請求成員'size',它是非型別別'int[n]'for(intj=arr.size()-1;j>
