我在最后几天编写node.js并大量使用异步库.它是一个库,它引入了处理异步编程中常见工作流的函数.有些函数可以并行或在另一个之后运行异步调用,并在所有函数完成后调用单个回调(或发生错误).
对于C++,有这样的图书馆吗?
我非常喜欢异步编程,但是大量的回调(所有这些都有错误处理等)都很难阅读和维护,并且有点难看.我希望以我对异步库的体验方式继续编码.
我想这样的库在C++等动态类型较少的语言中难以实现.
PS:建议如何使异步代码更漂亮也欢迎.
编辑:我正在使用g ++和C++ 11.
编辑2:"异步"意味着在此上下文中使用带有回调的非阻塞函数,而不是在后台运行并行线程.一个例子是boost:asio.
编辑3:我已经在使用boost :: asio,并希望用这样的库来增强代码的可读性(控制流的清晰度......).
正如你必须已经知道的那样,鉴于你正在使用它,boost.asio会让你成为那里的一部分.但它不会是一样的.让我解释一下原因.
node和asio都是围绕一个proactor的想法设计的.如果你想做阻塞(或者只是慢速)的事情,你将工作提交给proactor,它会在适当的时候运行,然后在完成时调用你的回调.
但在节点中,一切都通过了预测器; 没有其他类型的异步API.如果要与MySQL数据库通信,接口将获取SQL语句并使用行集回调.在C++中,接口接受一个SQL语句,并在给出游标之前阻塞,或者为您提供一个可以轮询或阻止的对象.对于文件和套接字,你可以忽略所有其他的API,select或者aio_read因为asio有完整的包装器,但对于其他任何东西,你必须完成编写包装器的工作,而且通常需要做很多工作.
更严重的是callback(error, result),节点中的标准回调接口result是JS对象,它可以包含任何适当的成员.在ASIO标准的回调接口是void callback(const error_code&),那里是没有结果.您将可变对象绑定到任务中.这已经使得控制流程变得更加笨拙,因为对象无法在不知道其前任如何隐藏其可变数据的情况下跟随另一个对象.这也意味着您需要共享的可变数据(与节点不同,可以跨线程共享),无论您是否需要它.但当然最大的问题是数据是静态类型的.(通常人们构建C++类,并通过将任务绑定到同一对象的方法来共享状态,但这实际上并不是必需的.)
当然,您可以编写代码来完成C++中的完全动态对象(或者只是动态性的一个级别,就像一个vector<boost::any>就足够了),但它仍然比使用JS更加笨拙,而且你会放弃很多通过转向C++,您希望获得的性能优势.
因此,编写像void async::waterfall(vector<void(const error_code&)>> tasks)这样的函数完全相同的东西会非常容易async.waterfall(tasks),但它不会给你带来所有你想要的好处.
另一个需要考虑的问题是,您已经切换到C++是有原因的:您处于一个缓慢的,资源受限的系统中.使用一个proactor实现数据并行,相当于async.forEach,并不是不可行的,但它不会像普通的旧线程池和知道如何使用它的并行库一样高效.
| 归档时间: |
|
| 查看次数: |
1422 次 |
| 最近记录: |