我需要在交互式应用程序中管理CPU繁重的多任务作业.同样背景,我的具体应用是工程设计界面.当用户调整模型的不同参数和选项时,会在后台运行多个模拟,并在完成时显示结果,即使用户仍在编辑值时也是如此.由于多次模拟需要可变时间(有些是几毫秒,有些需要5秒,有些需要10分钟),所以基本上是尽可能快地显示反馈,但通常会中止以前开始但现在不再需要的作业,因为用户的更改已经使它们无效.不同的用户更改可能使不同的计算无效,因此在任何时候我可能有10个不同的模拟运行.
我非常有信心处理这种应用程序的代码级方法是某种多线程作业队列.这将包括提交作业以执行,设置任务优先级,等待作业完成,指定依赖项(执行此作业,但仅在作业X和作业Y完成后),取消符合某些条件的作业子集,查询内容的功能工作仍然存在,设置工作线程计数和优先级等等.多平台支持也非常有用.
这些不是软件中的新想法或愿望,但我处于应用程序的早期设计阶段,我需要选择用于管理此类任务的库.我过去在C中编写了我自己的粗线程管理器(我认为这是一个通过的仪式)但我想使用现代工具来开展我的工作,而不是我以前的hacks.
首先想到的是运行OpenMP,但我不确定这是我想要的.OpenMP非常适合在精细级别进行并行化,自动展开循环等.虽然是多平台,但它也会用#pragmas侵入您的代码.但主要是它不是为管理大型任务而设计的.尤其是取消挂起的作业或指定依赖项.可能,是的,但它并不优雅.
我注意到Google Chrome使用这样的作业管理器来完成最琐碎的任务.设计目标似乎是保持用户交互线程尽可能轻巧灵活,因此任何可以异步生成的东西都应该是.从查看Chrome源代码来看,这似乎不是一个通用库,但看看设计如何使用异步启动来保持交互速度仍然很有趣.这与我正在做的类似.
还有其他选择:
Surge.Act:用于定义作业的类似Boost的库.它建立在OpenMP之上,但允许链接依赖项,这很好.它似乎并不觉得它有一个可以查询的经理,取消工作等等.这是一个陈旧的项目所以依赖它是可怕的.
Job Queue非常接近我的想法,但它是一篇5年前的文章,而不是受支持的库.
Boost.threads确实有很好的平台独立同步,但那不是一个职业经理.POCO具有非常干净的任务启动设计,但同样不是链接任务的完整经理.(也许我低估了POCO).
因此,虽然有可用的选项,但我不满意,我觉得再次推出自己的库的冲动.但我宁愿使用已经存在的东西.即使在搜索之后(这里在SO和网上)我也没有发现任何感觉正确的东西,尽管我认为这必须是一种经常需要的工具,所以肯定有一些社区库或至少是常见的设计.在SO上有关于工作队列的一些帖子,但似乎没有任何东西适合.
我在这里的帖子是问你所有我错过的现有工具,和/或你如何推出自己的多线程作业队列.
使用Visual Studio 2015,在一个新的空C++项目中,为Console应用程序构建以下内容:
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在返回时设置断点并在调试器中启动程序.在Windows 7上,从断点开始,该程序只有一个线程.但在Windows 10上,它有五个(!)线程:主线程和四个"工作线程"等待同步对象.
谁在启动线程池(或者我如何找到)?
是否有一个神奇的数字或公式来设置ThreadPool的SetMaxThreads和SetMinThreads的值?我有成千上万个需要执行的长时间运行方法,但却无法找到设置这些值的完美匹配.任何建议将不胜感激.
我可以想象一些任务计划花费很长时间,并ScheduledThreadPoolExecutor
为其他需要运行的任务创建额外的线程,直到达到最大线程数.
但似乎我只能为池指定固定数量的线程,为什么会这样呢?
在C#中,使用委托异步地执行某些工作(调用BeginInvoke())和使用ThreadPool线程之间有任何区别,如下所示
public void asynchronousWork(object num)
{
//asynchronous work to be done
Console.WriteLine(num);
}
public void test()
{
Action<object> myCustomDelegate = this.asynchronousWork;
int x = 7;
//Using Delegate
myCustomDelegate.BeginInvoke(7, null, null);
//Using Threadpool
ThreadPool.QueueUserWorkItem(new WaitCallback(asynchronousWork), 7);
Thread.Sleep(2000);
}
Run Code Online (Sandbox Code Playgroud)
编辑:
BeginInvoke确保线程池中的线程用于执行异步代码,所以有什么区别吗?
我的问题:如何在a上执行一堆线程对象ThreadPoolExecutor
并等待它们全部完成然后再继续?
我是ThreadPoolExecutor的新手.因此,此代码是一项测试,以了解它是如何工作的.现在我甚至没有填充BlockingQueue
对象,因为我不知道如何启动队列而不用execute()
另一个调用RunnableObject
.无论如何,现在我只是打电话,awaitTermination()
但我想我仍然缺少一些东西.任何提示都会很棒!谢谢.
public void testThreadPoolExecutor() throws InterruptedException {
int limit = 20;
BlockingQueue q = new ArrayBlockingQueue(limit);
ThreadPoolExecutor ex = new ThreadPoolExecutor(limit, limit, 20, TimeUnit.SECONDS, q);
for (int i = 0; i < limit; i++) {
ex.execute(new RunnableObject(i + 1));
}
ex.awaitTermination(2, TimeUnit.SECONDS);
System.out.println("finished");
}
Run Code Online (Sandbox Code Playgroud)
RunnableObject类:
package playground;
public class RunnableObject implements Runnable {
private final int id;
public RunnableObject(int id) {
this.id = id;
}
@Override
public void …
Run Code Online (Sandbox Code Playgroud) 我想用Go从Yahoo finance下载股票价格电子表格.我将为自己的goroutine中的每个股票发出http请求.我有一个大约2500个符号的列表,但不是并行地发出2500个请求,我宁愿一次做250个.在Java中,我创建了一个线程池,并在它们获得空闲时重用它们.我试图找到类似的东西,一个goroutine池,如果你愿意,但无法找到任何资源.如果有人能告诉我如何完成手头的任务或者为我指出相同的资源,我会很感激.谢谢!
我使用java.util.concurrent
的Executors
类来创建一个固定的线程池运行请求处理程序的Web服务器:
static ExecutorService newFixedThreadPool(int nThreads)
Run Code Online (Sandbox Code Playgroud)
而描述是:
创建一个线程池,该线程池重用一组在共享无界队列中运行的固定线程.
但是,我正在寻找线程池实现,它将执行完全相同的操作,除了有界队列.有这样的实施吗?或者我是否需要为固定线程池实现自己的包装器?
场景:我有一个示例应用程序,我有3种不同的系统配置 -
- 2 core processor, 2 GB RAM, 60 GB HHD,
- 4 core processor, 4 GB RAM, 80 GB HHD,
- 8 core processor, 8 GB RAM, 120 GB HHD
Run Code Online (Sandbox Code Playgroud)
为了有效地利用我的应用程序的H/W功能,我希望配置no.应用程序级别的线程数.但是,我希望在彻底了解系统功能之后才能这样做.
是否有某种方式(系统/模式/工具)来参考最大值和最小值来确定系统实力.它可以最佳地服务并且不会降低效率和性能.通过这种方式,我只能为我的应用程序配置那些能够完全正义并为各自的硬件配置实现最佳性能的值.
Edited1: 任何人都可以建议任何关于如何为特定h/w配置设置基线的读数.
编辑2: 使其更直接 - 希望学习/了解我可以阅读的任何资源/文章,以获得对一般/整体级别的线程CPU管理的一些了解.