Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get a thread id inside parallel.ForEach loop

Is there a way to find the thread id inside Parallel.FoEach loop. I tried using var threadId = Thread.CurrentThread.ManagedThreadId - 1;, but it didn't give me the correct index I was looking for.

Here is an simple example:

private void TestProgram()
    {
        int numThreads = 1;

        var values = new List<float>();
        for (int i = 0; i < numThreads; ++i)
        {
            values.Add(i);
        }

        var data = new List<int>();
        for (int i = 0; i < numThreads; ++i)
        {
            data.Add(i);
        }


        Parallel.ForEach(data, new ParallelOptions{MaxDegreeOfParallelism = numThreads}, i =>
            //foreach (var i in data)
        {
            var threadId = Thread.CurrentThread.ManagedThreadId - 1; // make the index to start from 0

            values[threadId] += i;
        });
    }

Even after setting the MaxDegreeOfParallelism to 1, I still get the threadId to be greater than 1.

Is there a way to find the thread id inside Parallel.ForEach in above scenario?

Note: I could have used Parallel.For in the example I used. But my question is to find it inside Parallel.ForEach

like image 676
veda Avatar asked Aug 27 '15 15:08

veda


People also ask

Is parallel ForEach multithreaded?

Parallel. ForEach is like the foreach loop in C#, except the foreach loop runs on a single thread and processing take place sequentially, while the Parallel. ForEach loop runs on multiple threads and the processing takes place in a parallel manner.

Does parallel ForEach use ThreadPool?

Parallel. ForEach uses managed thread pool to schedule parallel actions. The number of threads is set by ThreadPool.

Is parallel ForEach faster than ForEach?

The execution of Parallel. Foreach is faster than normal ForEach.

Does ForEach work in parallel?

ForEach loop works like a Parallel. For loop. The loop partitions the source collection and schedules the work on multiple threads based on the system environment. The more processors on the system, the faster the parallel method runs.


2 Answers

Since Parallel.ForEach is part of the Task Library, Task.CurrentId will get you closer to what you are looking for:

   var data = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };


   Parallel.ForEach(data, new ParallelOptions { MaxDegreeOfParallelism = 4 }, i =>
   {
            Console.WriteLine(Task.CurrentId);
   });

output is 1 1 1 1 1 1 1 1 1 1 2 2 1

However, there is a disclaimer in the docs:

Task IDs are assigned on-demand and do not necessarily represent the order in which task instances are created. Note that although collisions are very rare, task identifiers are not guaranteed to be unique.

like image 175
user957902 Avatar answered Sep 23 '22 06:09

user957902


ThreadIDs are assigned by the underlying environment, and have no guarantee of being from 0 to [num of threads] or even being consistent from run to run.

There's only a few contracts with respect to threadIDs, and even these aren't guaranteed:

  • You won't get a ThreadID 0
  • ThreadID 1 is usually reserved for the Main thread
like image 31
Xirema Avatar answered Sep 22 '22 06:09

Xirema