我想基于Asio 1.19.2(不帶 boost)撰寫自己的異步函式。
其動機是創建一個與類似JSON-RPC的協議(不完全是 JSON-RPC)一起使用的介面。
在插座上它看起來像
--> { "method": "subtract", "params": [42, 23], "id": 1 }
<-- ... some irrelevant notifications, etc.
<-- { "result": 19, "id": 1 } <-- ID matches initial call
我使用std::futures(沒有 Asio)解決了這個問題。該方法簽名類似于:
// near useless, because futures don't allow for continuation
std::future<std::string> json_rpc(std::string method, json::array args);
為了實作這一點,我只需要:
- 保持套接字在后臺打開(它也可以傳遞給方法或其他任何東西)。
- 存盤一組掛起的承諾。
- 當您呼叫 時
json_rpc,創建一個新的承諾,將其添加到集合中,回傳get_future(). - 在套接字上發送 RPC。
- 如果您
{ "result" ... }在套接字上收到一條訊息,請找到具有該 ID 的未決未來set_value()及其promise結果。
我如何將這種基于未來的方法轉換為基于 asio 的方法,它具有與 eg 類似的介面async_read_until?換句話說,我想實作類似的東西:
template <typename CompletionToken>
void async_json_rpc(std::string method, json::array args, CompletionToken&& completion_token);
我從 beast找到了這個教程,但它使用了 Boost.Beast,看起來已經過時了,它唯一的異步部分是它呼叫async_read_some. 我的代碼并不能真正使用這些 asio async_“原語”,因為我的完成處理程式需要在作業系統控制之外的某個時間被呼叫。
我還從 asio docs 中找到了這些示例,但它們具有相同的限制,即僅包裝其他async_呼叫。對于應用程式代碼,它們也變得越來越復雜,難以管理。
我想,我的問題的核心是:我有一個 async 函式,它基本上像asio::use_future用作它的CompletionToken. 我如何讓它使用任何一種CompletionToken?promise.set_value()asio 完成處理程式的等效項是什么?
我對簡單易懂的解決方案非常感興趣,因此我不是團隊中唯一能夠維護這些功能的人。
uj5u.com熱心網友回復:
我想你是在問如何實作“鏈”?我做過類似的事情。
通常,您需要一個為佇列提供服務的作業執行緒。它將回圈并執行佇列中的每個專案,但在它為空時休眠。如有必要,向佇列中添加一些內容將通知執行緒喚醒。
一個更好的變體是使用執行緒池和公共佇列,如果您有太多執行緒,則修剪多余的執行緒,如果現有執行緒有太多作業,則創建更多執行緒。最佳情況下,這需要作業系統支持(我已經為 Windows 完成埠實作了這一點)。
當你想做一些異步的事情時,你將承諾放在佇列中,而不是為此啟動一個專用執行緒。
或者……你在看協程,co_await用 C 呼叫嗎?
uj5u.com熱心網友回復:
聽起來您沒有任何“自定義”異步操作。
您的所有專案符號都可以在async_read或 的完成處理程式中實作async_write。
- 當您呼叫 時
json_rpc,創建一個新的承諾,將其添加到集合中,回傳get_future().
是的,這很好。如果 I/O 服務在單獨的執行緒中運行,請確保使用互斥鎖保護任何共享狀態。
- 在套接字上發送 RPC。
就在回傳之前future,呼叫async_write以發送請求。使用 astrand來序列化寫入(請記住,async_write可能只有一個在進行中)。
在稍后階段,如果您發現自己在負載下需要更好的性能,您可以放棄該鏈并使用待處理請求佇列“手動”進行排隊。然后,您將能夠在單個async_write操作中發送所有掛起的請求,這會將它們打包成更大的 TCP 資料包,從而提高吞吐量。
- 如果您
{ "result" ... }在套接字上收到一條訊息,請找到future具有該 ID的待處理項set_value()及其對結果的承諾。
這正是在 的完成處理程式中完成的async_read。async_read在從 回傳之前再開火async_read。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/317344.html
上一篇:奇怪的輸出C
