有没有办法限制ThreadPool对象将使用的处理器数量?根据文档,“您不能将工作线程数或I / O完成线程数设置为小于计算机中处理器数量的数字。”
那么如何限制我的程序不使用所有处理器呢?
答案 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。