1

我们正在设计一个应用程序,用户可以在其中设置同时运行的多个任务。我们使用 ThreadPool.QueueUserWorkItem 来设置任务运行。那部分运行良好。

我们确实有一个问题,这些任务会消耗 500MB 以上的内存。我们使用内存映射 I/O 来管理内存。仍然当用户设置 10+ 个任务同时运行时,线程池将启动所有这些任务,并且有时我们会耗尽内存并发生异常。我们可以很好地处理错误。

我想知道是否有办法在处理队列时考虑将消耗的内存,即保持任务排队直到存在足够的内存?我可以告知线程池我们将要求多少内存(我们可以粗略估计)吗?

4

3 回答 3

0

ThreadPool 对您在任务中执行的操作一无所知。您需要自己确保这一点。您可以管理一个 long 类型的全局变量,该变量表示所有正在运行的作业在峰值时可能需要的总字节数。当线程池调度您的一项任务时,您首先检查该变量。如果它已经太高,请等到当前正在运行的任何任务退出。然后你再检查一次。

对此的低技术解决方案是使用具有 100 毫秒睡眠间隔的轮询。高科技版本将使用某种涉及事件的等待方案。

于 2012-01-27T16:04:11.050 回答
0

您可以通过 ThreadPool.SetMaxThreads 控制线程池中的线程数。所以你可以做的是设置你的最大线程数

ThreadPool.SetMaxThreads = new PerformanceCounter("Memory", "Available MBytes").RawValue / 500;

PerformanceCounter("Memory", "Available MBytes").RawValue -> 以 MB 为单位返回可用内存

于 2012-01-27T16:31:23.150 回答
0

好的,如果您可以获得每个任务的内存估计,您可以通过在池中保留粗略的受 CS 保护的内存使用计数来做到这一点。在提交任务之前添加到此计数,并让任务调用“memRelease”函数以在它结束之前从中减去,并检查现在是否可以运行任何东西,(见下文)。

如果某个线程想要提交任务并且发现(通过将其需求与 CS 内的当前使用情况进行比较),“预算”中没有足够的内存来运行它,您可以将其推入并发队列/list 等到有。每当任务完成并调用“memRelease”时,它都会添加到内存 buget 并迭代队列/列表(首先锁定它),以尝试找到现在可以使用增加的可用内存运行的东西。如果是,它会将任务提交到池中。

于 2012-01-27T16:20:52.913 回答