asio的作者Christopher Kohlhoff正在为C ++中的执行者提供一个库和提案。到目前为止,他的工作包括repo和docs。不幸的是,理由部分还没有写出来。到目前为止,文档提供了一些图书馆的例子,但我不觉得我错过了什么。不知何故,这不仅仅是一系列奇特的调用函数。
我在Google上可以找到的所有东西都是特定于Java的,并且很多特定于特定框架,所以我无法弄清楚这个“执行器模式”是什么。
在这种情况下,执行者是什么?他们在做什么?什么时候它们有用的规范示例是什么?执行人之间存在哪些差异?执行者有哪些替代方案,他们如何比较?特别是,事件循环似乎与事件是初始输入事件,执行事件和关闭事件有很多重叠。
当试图找出新的抽象时,我通常会发现理解动机的关键。那么对于执行者来说,我们想要抽象的是什么?为什么?我们试图制作通用的是什么?没有遗嘱执行人,我们还需要做多少工作?
答案 0 :(得分:1)
执行程序的最基本好处是将程序并行性的定义与使用方式分开。之所以存在Java的执行器模型,是因为实际上,您实际上并不知道在首次编写代码时哪种并行性模型最适合您的情况。您可能从并行性中获益甚微,根本不应该使用线程,对于长时间运行每个内核的专用工作线程,或者根据当前负载动态缩放线程池以在线程运行后清除线程,您可能会做到最好空闲了一段时间以减少内存使用,上下文切换等,或者只是为每个任务按需启动线程,完成任务后退出。
这里的关键是,在您首次编写代码时,几乎不可能知道哪种方法是最佳的。您可能知道并行性可能在什么地方为您提供帮助,但是在传统线程中,您最终会通过使用并行性(确定要调用的函数)将并行性“配置”(何时以及是否创建线程)混合在一起什么参数)。当您像这样混合使用代码时,对每个选项进行性能测试是很痛苦的,因为每个线程启动都是独立的,并且必须分别进行更新。
执行程序模型的主要优点是,并行配置是在一个位置(创建执行程序的位置)进行的,而其中的 users 执行者不必对此有任何了解。他们只是将工作提交给执行者,得到未来,然后在以后的某个时间点,从将来检索结果(如有必要,阻止)。如果要尝试其他配置,则更改定义执行程序的一行,然后再次运行代码。与手动重写每个站点的线程详细信息相比,即使您决定需要为代码的不同部分使用不同的并行模型,也可以进行重构以添加第二个执行器并更改第一个执行器的某些用户以使用第二个执行器。 ;只要执行者的名称是(相对)唯一的,查找用户并将其更改为使用其他用户就很容易。执行程序既简化了代码(避免了将线程的创建/管理与线程执行的任务混在一起),又简化了性能测试。
作为附带的好处,您还抽象了将数据传入和传出工作线程的复杂性(submit方法封装了前者,future的result
方法封装了后者)。 std::async
会为您带来一些好处,但是并不能真正控制所涉及的并行性(是/否/也许是强制执行线程,在当前线程中强制执行延迟执行还是让编译器/库决定是否对线程池是否使用以及是否使用线程池进行细粒度的控制)。真正的执行程序框架可为您提供std::async
无法提供的控件,并且具有类似的易用性。