简体   繁体   中英

Limit number of processors used in ThreadPool

Is there any way to limit the number of processors that the ThreadPool object will use? According to the docs, "You cannot set the number of worker threads or the number of I/O completion threads to a number smaller than the number of processors in the computer."

So how can I limit my program to not consume all the processors?

After some experiments, I think I have just the thing. I've noticed that the ThreadPool considers the number of processors in the system as the number of processors available to the current process . This can work to your advantage.

I have 4 cores in my CPU. Trying to call SetMaxThreads with 2:

ThreadPool.SetMaxThreads(2, 2);

fails since I have 4 cores and so the numbers remain at their initial values (1023 and 1000 for my system).

However, like I said initially, the ThreadPool only considers the number of processors available to the process, which I can manage using Process.ProcessorAffinity . Doing this:

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

limits the available processors to the first two cores (since 3 = 11 in binary). Calling SetMaxThreads again:

ThreadPool.SetMaxThreads(2, 2);

should work like a charm (at least it did for me). Just make sure to use the affinity setting right at program start-up!

Of course, I would not encourage this hack , since anyway your process will be stuck with a limited number of cores for the entire duration of its execution.

Thread pool was specifically designed to remove all the headache of manual managing of threads. OS task scheduler has been worked on for many years and is doing a very good job at scheduling tasks for execution. There are multiple options that the scheduler considers, such as thread priority, memory location and proximity to the processor etc. Unless you have deep understanding of these processes, you better off from setting thread affinity.

If I may quote docs

Thread affinity forces a thread to run on a specific subset of processors. Setting thread affinity should generally be avoided, because it can interfere with the scheduler's ability to schedule threads effectively across processors. This can decrease the performance gains produced by parallel processing. An appropriate use of thread affinity is testing each processor.

It is possible to set a Thread affinity though (relevant post ), for which you will need to create your own thread object (and not the one from thread pool). To my limited knowledge, you cannot set a thread affinity for a thread from a pool.

Since SetMaxThreads doesn't allow you to set no. of threads lower than no. of processors your net best bet is to write your own TaskScheduler in TPL that limits the concurrency by queuing the tasks. And then instead of adding items to threadpool, you can create tasks with that scheduler.

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

You don't typically limit the threadpool, you throttle the number of threads your program spawns at a time. The Task Parallel Library lets you set MaxDegreeOfParallelism , or you can use a Semaphore .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM