Reputation: 589
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
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
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