2012-07-11 21 views
3

是否有任何方法来限制ThreadPool对象将使用的处理器数量?根据文档,“您不能将工作线程数量或I/O完成线程数设置为小于计算机中处理器数量的数字。”ThreadPool中使用的处理器数量限制

那么我怎么能限制我的程序不消耗所有的处理器?

+5

你为什么要这么做? – svick 2012-07-11 11:54:48

+0

因为我的处理器上有8个内核,所以我希望当我运行它时锁定我的机器,我正在运行的进程不会占用我CPU的100%。 – tuj 2012-07-11 16:03:51

+1

如果它锁定了你的机器,你可以通过设置进程的优先级来解决这个问题。我不确定强制处理器的数量会有所帮助。 – svick 2012-07-11 16:23:44

回答

8

经过一番实验,我觉得我只是那件事。我注意到ThreadPool认为系统中处理器的数量为当前进程可用的处理器数量。这可以发挥你的优势。

我的CPU有4个内核。试图调用SetMaxThreads以2:因为我有4个核心,因此该数字保持在它们的初始值(1023和1000我的系统)

ThreadPool.SetMaxThreads(2, 2); 

失败。

然而,正如我最初所说的,ThreadPool只考虑了可用于处理的处理器数量,我可以使用Process.ProcessorAffinity来管理。这样做:

Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(3); 

将可用处理器限制为前两个内核(因为3 = 11,二进制)。再次调用SetMaxThreads

ThreadPool.SetMaxThreads(2, 2); 

应该像一个魅力(至少它为我做的)。只要确保在程序启动时使用亲和力设置!

当然,我不会鼓励这个hack,因为无论如何,在整个执行过程中,您的进程将被限制数量的核心卡住。

+0

非常好,工作完美! – tuj 2012-07-11 16:12:59

1

由于SetMaxThreads不允许您设置no。低于no的线程数。的处理器,你最好的选择是在TPL中编写你自己的TaskScheduler,它通过排队任务来限制并发。然后,而不是将项目添加到线程池,您可以使用该调度程序创建任务。

How to: Create a Task Scheduler That Limits the Degree of Concurrency

+0

您是否阅读过该问题中的报价?您不能将线程数设置为低于处理器数的数字。 – svick 2012-07-11 12:01:55

+0

@svick没有注意到这一点。更新了答案。 – 2012-07-11 12:10:33

1

你通常不会限制线程池,你扼杀你的程序会生成在时间的线程数。 Task Parallel Library可让您设置MaxDegreeOfParallelism,或者您可以使用Semaphore

+1

您能否解释* TPL提供了哪些方法? – svick 2012-07-11 12:03:04

+0

在这篇文章中还有一些有趣的讨论:http://stackoverflow.com/questions/2521840/multithreading-or-task-parallel-library – 2012-07-11 12:14:40

+0

'MaxDegreeOfParallelism'特定于'Parallel.ForEach()'和其他方法' Parallel'。除此之外无法使用。 – svick 2012-07-11 12:38:25

5

线程池专门用于消除所有手动管理线程的头痛问题。 OS任务调度程序已经工作了很多年,并且在执行任务计划方面做得非常好。调度程序考虑了多个选项,例如线程优先级,内存位置和处理器接近度等。除非您对这些过程有深入的了解,否则最好不要设置线程关联。

如果我可以引述docs

线程亲和力强制线程上 处理器的特定子集上运行。通常应避免设置线程关联,因为它可能会干扰调度程序在不同处理器间有效调度线程的能力。这可以降低并行处理产生的性能增益。 线程关联的适当使用 正在测试每个处理器。

它可以设置一个Thread亲和力虽然(相关post),为此,你需要创建自己的线程对象(而不是从一个线程池)。据我有限的知识,你无法为池中的线程设置线程关联。

相关问题