首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以在Parallel.ForEach执行期间更改parallelOptions.MaxDegreeOfParallelism

是否可以在Parallel.ForEach执行期间更改parallelOptions.MaxDegreeOfParallelism
EN

Stack Overflow用户
提问于 2010-09-14 06:52:41
回答 2查看 11.6K关注 0票数 19

我正在运行一个多线程循环:

代码语言:javascript
复制
protected ParallelOptions parallelOptions = new ParallelOptions();

parallelOptions.MaxDegreeOfParallelism = 2;
Parallel.ForEach(items, parallelOptions, item =>
{
// Loop code here
});

我想在并行循环执行期间更改parallelOptions.MaxDegreeOfParallelism,以减少或增加线程的数量。

代码语言:javascript
复制
parallelOptions.MaxDegreeOfParallelism = 5;

它似乎不会增加线程。有谁有什么想法吗?

EN

回答 2

Stack Overflow用户

发布于 2010-09-14 14:05:31

尝试这样做的问题是,这是一个很难解决的问题。对于初学者来说,如何可靠地观察CPU和磁盘利用率?如果不频繁地对CPU进行采样,将无法清楚地了解实际发生的情况,并且对磁盘利用率进行采样会更加困难。其次,您的任务的粒度是多少,以及您可以多快地更改正在运行的数量。第三,随着时间的推移,事情会迅速变化,所以你需要对你的观察结果进行某种过滤。第四,理想的线程数取决于实际运行代码的CPU。第五,如果你分配了太多的线程,你会在它们之间翻来覆去,而不是做有用的工作。

有关.NET中的线程池如何处理决定使用多少线程这一复杂任务的讨论,请参阅http://msdn.microsoft.com/en-us/magazine/ff960958.aspx

你也可以使用反射器,看看TPL用来分配线程和避免不必要的上下文切换的代码-它很复杂,甚至没有考虑磁盘访问!

相反,您可以尝试在较低优先级的线程上执行任务(创建自己的TaskScheduler来运行优先级低于正常的线程实际上非常容易)。这至少将确保您可以在不影响系统其余部分的情况下运行100%的CPU。扰乱线程优先级本身就充满了问题,但如果这是一个纯粹的后台任务,那么它可能会很简单,而且可能会有所帮助。

然而,当其他应用程序受到贪婪的应用程序的影响时,磁盘利用率往往是真正的罪魁祸首。Windows可以很容易地在应用程序之间公平地分配CPU,但当涉及到相对较慢的磁盘访问时,就完全是另一回事了。您不需要尝试动态地调整正在运行的线程的数量,而是只需要对应用程序进行限制,这样它就不会频繁地访问磁盘。这是您可以在不更改活动线程数量的情况下完成的事情。

您还可以将SetPriorityClass视为通知操作系统您的进程不如系统上运行的其他应用程序重要的一种方式,有关更多信息,请参见How can I/O priority of a process be increased?。但这假设你的整个过程不那么重要,而不仅仅是这一部分。

票数 6
EN

Stack Overflow用户

发布于 2010-09-14 07:35:29

我不希望在你调用ForEach之后改变并行度是可能的。据我所知,ForEach将确定它可以创建多少个线程,创建那么多个分区,并创建在这些分区上操作的线程。它不可能会说,“哦,等等,他改变了我们的资源分配,让我重新划分数组并重新分配线程。”

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3705006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档