Why when I run the following example do I only have the Parallel.ForEach run the number of threads equal to the number of cores on my machine? I thought Parallel.ForEach gives you thread pool threads of which there are approx 1000?
int threads1;
int threads2;
ThreadPool.GetAvailableThreads(out threads1,out threads2);
var list = Enumerable.Range(1, 200);
var po = new ParallelOptions
{
MaxDegreeOfParallelism = 100
};
Parallel.ForEach(list, po, x =>
{
Console.WriteLine("Thread:" + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000);
});
Am I missing something here?
Parallel.ForEach
uses managed thread pool to schedule parallel actions. The number of threads is set by ThreadPool.SetMinThreads
and ThreadPool.SetMaxThreads
. By default, the minimum number of threads is set to the number of processors on a system.
To minimize the usage of system resources, the number of pool threads is kept as low as possible. When all the pool threads are busy executing actions, the scheduler gradually spawns new threads.
The value MaxDegreeOfParallelism
is usually used to prevent Parallel.For
from scheduling more than the specified number of tasks simultaneously. It is useful in case of long computations when there is no sense of using more threads than the number of cores.
If you modify the code by increasing the sleep time Thread.Sleep(100000);
, you will see the creation of new threads.
If you call ThreadPool.SetMinThreads(100, 100);
before Parallel.ForEach
, you will see all 100
actions started simultaneously.
You will get the best performance if the number of threads doesn't exceed the number of processing cores.
Each core can only process one thread at a time. If there are more threads than cores, the OS has to switch between threads. Context switching is an expensive operation, you should try to avoid it in multi-threaded applications.
If the operations you perform are IO-bound, you should use Task
s instead of Paraller.For
. It's nicely explained on Scott Hanselman's blog.
The details of Parallel.For
thread management are explained in details in Andrey Nasonov's answer, so I will not repeat it.
If you want to learn more about threading, TPL and asynchrounous I/O I recommend CLR via C# book
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With