限制ThreadPool中使用的处理器数量

时间:2012-07-11 11:53:18

标签: c# .net multithreading threadpool

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

那么如何限制我的程序不使用所有处理器呢?

4 个答案:

答案 0 :(得分:9)

经过一些实验,我认为我有这个东西。我注意到ThreadPool认为系统中处理器的数量为当前进程可用的处理器数量。这对您有利。

我的CPU中有4个核心。试着用2:

打电话给SetMaxThreads
ThreadPool.SetMaxThreads(2, 2);

失败,因为我有4个核心,所以数字保持在它们的初始值(我的系统为1023和1000)。

但是,正如我最初所说,ThreadPool仅考虑流程可用的处理器数量,我可以使用Process.ProcessorAffinity来管理。这样做:

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

将可用处理器限制为前两个核心(因为3 = 11的二进制)。再次致电SetMaxThreads

ThreadPool.SetMaxThreads(2, 2);

应该像魅力一样(至少它对我有用)。只需确保在程序启动时使用亲和力设置!

当然,我不会鼓励这种 hack ,因为无论如何,你的进程在整个执行期间都会遇到有限数量的内核。

答案 1 :(得分:5)

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

如果我引用docs

  

线程亲和力强制线程在特定子集上运行   处理器。通常应避免设置线程亲和力,   因为它会干扰调度程序的计划能力   跨处理器有效的线程。这可以减少   并行处理产生的性能提升。 适当使用   线程关联性测试每个处理器。

可以设置Thread亲和力(相关post),您需要为此创建自己的线程对象(而不是线程池中的对象)。据我所知,您无法为池中的线程设置线程关联。

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

您通常不会限制线程池,而是限制程序一次生成的线程数。 Task Parallel Library允许您设置MaxDegreeOfParallelism,或者您可以使用Semaphore