Mohammad
Mohammad

Reputation: 589

local variable inside parallel loops thread safety

I have a variable (cnt) inside nested parallel.foreach. I run this program and apparently it works well. Does anybody know this code is really thread safe? Is it possible to define variable inside parallel loops?

Thank you.

    object obj = new object();
    int total=0;

    Parallel.For(0, 2, i =>
    {
        Parallel.For(0, 1000000, j =>
        {
            int cnt = 0;
            if ((arr[i, j] % 2) == 0)
            {
                Interlocked.Increment(ref cnt);
            }
            lock (obj)
            {
                total= total+ (cnt / 2);
            }
        });
    });

Upvotes: 4

Views: 7196

Answers (2)

Reed Copsey
Reed Copsey

Reputation: 564373

This code is thread safe - the only shared data (total) is properly synchronized. It's threadsafe even without using Interlocked.Increment (ie: prior to your edit).

However, it is not efficient.

It would be far better to use the overload with local initializer and finally delegates.

int total=0;
Parallel.For(0, 2, 
{
    Parallel.For(0, 1000000, 
      local => 0,
      (j, state, local) =>
      {
        if ((arr[i, j] % 2) == 0)
        {
           ++local;
        }
        return local;
      },
      local => Interlocked.Increment(ref total, local)
    );
});

Upvotes: 6

JaredPar
JaredPar

Reputation: 754575

This code is indeed safe because the lock statement acts as a full fencing operation. It ensures that the increment operation is atomic and won't be subject to races from other threads

Upvotes: 0

Related Questions