c++ - 如何使用(非增强)Asio 编写自己的异步操作?
问题描述
我想基于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::future
s (没有 Asio)解决了这个问题。该方法签名类似于:
// near useless, because futures don't allow for continuation
std::future<std::string> json_rpc(std::string method, json::array args);
为了实现这一点,我只需要:
- 保持套接字在后台打开(它也可以传递给方法或其他)。
- 存储一组待处理的 Promise。
- 当您调用 时
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_
调用的相同限制。对于应用程序代码,它们也变得越来越复杂。
我想,我的问题的核心是:我有一个异步函数,它基本上就像它asio::use_future
用作它的CompletionToken
. 我如何让它使用任何一种CompletionToken
?promise.set_value()
asio 完成处理程序的等价物是什么?
我对简单易懂的解决方案非常感兴趣,因此我不是团队中唯一能够维护这些功能的人。
为了进一步澄清(根据我的评论):
我已经实现了“服务线程的服务完成”,但我只支持期货(如果我正在编写一个 asio 异步方法,就好像我只做了 asio::use_future 重载)。我在问如何支持 CompletionHandlers,即如何编写其他可以采用 lambdas 或 yield_contexts 的 async_* 重载。
解决方案
我想您是在问如何实施“链”?我做过类似的事情。
通常,您需要一个为队列提供服务的工作线程。它将循环并执行队列中的每个项目,但当它为空时会休眠。如有必要,将某些内容添加到队列中会通知线程唤醒。
一个更好的变体是使用线程池和公共队列,如果有太多线程,则修剪多余的线程,如果现有线程的工作过多,则创建更多线程。理想情况下,这需要操作系统支持(我已经为 Windows 完成端口实现了这个)。
当你想做一些异步的事情时,你把承诺放在队列上,而不是为此启动一个专用线程。
或者......你在看协程,co_await
在 C++ 中进行调用吗?
推荐阅读
- python - Python:获取 concurrent.futures 执行程序以等待 done_callbacks 完成
- php - 订购特定产品后发送带有用户凭据的自定义 WooCommerce 邮件
- android - 使用片段和导航组件泄漏的nestedscrollView
- pdf - 如何解码PDF文件并将其编码回来?
- spring - 如何正确地将身体传递给弹簧休息模板?
- javascript - redux状态改变时如何触发函数?
- alexa - 将预置并发添加到已发布的 Alexa Skill 需要哪些步骤?
- swift - 缩放到 iPhone 上滚动视图上的位置(纵向);不太对
- python - 如果不存在,Pandas 通过查找最小列进行分组返回 NaN
- spring-integration - Spring集成HTTP出站网关根据回复内容重试