Reputation: 523
What I want to achieve:
Using Parallel.For
(anything else would be appreciated, but found out that this one is the easiest) I want to increase a variable named max
so that it gets to 100,000,000
, using threads, but the program should use only X number of threads at the same time.
Code snippet:
using System;
using System.Threading;
using System.Linq;
using System.Threading.Tasks;
using System.Diagnostics;
namespace pool_threading
{
class MainClass
{
static int max=0;
static int current_max_thread=0;
public static void Main (string[] args)
{
Parallel.For(0, 100000000, new ParallelOptions { MaxDegreeOfParallelism = 50 },
i =>
{
max++;
if(Thread.CurrentThread.ManagedThreadId>current_max_thread)
current_max_thread=Thread.CurrentThread.ManagedThreadId;
});
Console.WriteLine ("I got to this number {0} using most {1} threads",max,current_max_tread);
}
public static void GetPage(int i)
{
}
}
}
Result:
I got this number 38,786,886
using most 11 threads
Now ... I don't know why I get the number 38,786,886
which is less than 38,786,886
, but I guess it's because multiple threads are trying to increase it at the exact same time, so if 10 are trying at the same time, only the first one will get the chance. Please correct me if I'm wrong.
The biggest "problem" is that I get 11 threads all the time, even with the maximum set to 50 (scroll the code to see the maximum), if I set it to maximum 1 thread, I get always 4 (maybe 4 is the minimum in this situation, but it still doesn't explain why I get maximum only 11 at the same time).
Upvotes: 0
Views: 246
Reputation: 1712
I believe you are not getting 50 threads for 2 main reasons:
Hardware. There is a point at which a processor can do more with fewer threads because the time it takes to switch threads is more than just running a thread more often. This leads to
Managed code. C#.NET is a managed code system. The programmers of .Net know the above and probably set some limits and checks to prevent too many threads from running. What you are setting in the code might be above some internal limit, so it is effectively ignored. Also, you are setting a maximum, so the Parallel.For() can use anywhere from 1 to X number of threads, whatever it thinks is most efficient.
Upvotes: 0
Reputation: 108651
There are two things going on here, as far as I can see:
First, you are hammering away on max
from multiple threads. You probably have a multicore machine. Those operations are probably overlapping with each other. To perform your incrementing in a thread safe way you need
Interlocked.Increment(ref max);
not
max++; /* not thread safe */
Second, you don't always get the number of threads you asked for in MaxDegreeOfParallelism
. You'll never get more, but you might get less.
If you're going to use parallelism please pay close attention to the thread-safety of the code you'll run in the threads.
Upvotes: 1
Reputation: 203820
This is trivial, just use i
inside of the loop instead of trying to increment and use max
. You're not incrementing it safely, but there's not reason for you to try. The whole point of Parallel.For
is that it gives you the loop index, and ensures that each loop index is hit exactly once, no more, no less.
Upvotes: 2