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