我需要在交互式应用程序中管理占用大量 CPU 的多任务作业。作为背景,我的具体应用是一个工程设计界面。当用户调整模型的不同参数和选项时,会在后台运行多个模拟,并在完成时显示结果,即使用户仍在编辑值也是如此。由于多次模拟需要不同的时间(有些是毫秒,有些需要 5 秒,有些需要 10 分钟),因此基本上是尽快显示反馈的问题,但通常会中止以前开始但现在不再需要的作业,因为用户的更改已经使它们无效。不同的用户更改可能会使不同的计算无效,因此在任何时候我都可能运行 10 个不同的模拟。
我非常有信心处理这种应用程序的代码级方法是某种多线程作业队列。这将包括提交作业以执行、设置任务优先级、等待作业完成、指定依赖关系(执行此作业,但仅在作业 X 和作业 Y 完成后)、取消符合某些条件的作业子集、查询什么作业保留,设置工作线程计数和优先级,等等。多平台支持也非常有用。
这些不是软件中的新想法或新愿望,但我正处于应用程序的早期设计阶段,我需要选择使用哪个库来管理此类任务。我过去用 C 编写了自己的粗略线程管理器(我认为这是一种通过仪式),但我想使用现代工具来作为我工作的基础,而不是我自己以前的 hack。
第一个想法是运行到OpenMP,但我不确定这是我想要的。OpenMP 非常适合精细并行化、自动展开循环等。虽然是多平台的,但它也会使用#pragmas 侵入您的代码。但大多数情况下,它不是为管理大型任务而设计的。尤其是取消挂起的作业或指定依赖项。可能,是的,但它并不优雅。
我注意到即使是最琐碎的任务,谷歌浏览器也会使用这样的作业管理器。设计目标似乎是使用户交互线程尽可能轻巧灵活,因此任何可以异步生成的东西都应该是。从 Chrome 源代码来看,这似乎不是一个通用库,但看看设计如何使用异步启动来保持快速交互仍然很有趣。这越来越类似于我正在做的事情。
还有其他选择:
Surge.Act:用于定义工作的类似 Boost 的库。它建立在 OpenMP 之上,但确实允许链接依赖项,这很好。似乎没有可以查询的经理,可以取消工作等。这是一个陈旧的项目,因此依赖它很可怕。
Job Queue与我的想法非常接近,但这是一篇 5 年前的文章,而不是受支持的库。
Boost.threads确实有很好的平台独立同步,但这不是一个作业管理器。POCO具有非常简洁的任务启动设计,但同样不是用于链接任务的完整管理器。(也许我低估了 POCO)。
因此,虽然有可用的选项,但我并不满意,我有再次推出自己的图书馆的冲动。但我宁愿使用已经存在的东西。即使在搜索之后(在 SO 和网络上),我也没有找到任何感觉正确的东西,尽管我认为这一定是一种经常需要的工具,所以肯定有一些社区库或至少是通用设计。在 SO 上有一些关于工作队列的帖子,但似乎没有什么合适的。
我在这里的帖子是问你们我错过了哪些现有工具,和/或你们是如何推出自己的多线程作业队列的。