4

I have a time-consuming static C# method for creating an array (of double:s) and have therefore parallelized the operation.

Since I am creating the array before entering the loop and not tampering with its reference after that, I am thinking that it should be sufficient to lock the array itself while updating it within the parallel loop.

Is it OK to lock on the array itself or would I potentially face some performance or deadlock problems with this approach? Is it better to create a separate lock variable to put the lock on?

Here is some sample code to illustrate:

static double[] CreateArray(int mn, int n)
{
  var localLock = new object();    // Necessary?
  var array = new double[mn];

  Parallel.For(0, n, i =>
  {
    ... lengthy operation ...

    lock (array)    // or is 'lock (localLock)' required?
    {
      UpdatePartOfArray(array);
    }
  });

  return array;
}
9
  • 3
    If at any point during the "...lengthy operation..." code you are reading from the array, then you (might) have a race condition. Commented Jun 15, 2012 at 6:14
  • 1
    Why do you need to lock the array? Do the parallel operations touch the same elements in the array? If so, how much overlap is there between ops? Commented Jun 15, 2012 at 6:14
  • 1
    It would only be a race condition if you're reading an array value another thread could potentially change. If each iteration is totally isolated from the others (only reads and writes from one index, for instance, and each iteration gets a unique index) then there would be no problem. Commented Jun 15, 2012 at 6:22
  • 1
    If your operations are touching the same elements, then (in the general case) more co-ordination is needed than a simple lock, since you can have race conditions, etc. If there is no overlap, then no locking is necessary. Commented Jun 15, 2012 at 6:25
  • 1
    If you put the entire loop body in a lock in the general case, that would work. But it would defeat the point of using a parallel foreach loop to do that. Not all problems benefit equally from threading Commented Jun 15, 2012 at 6:29

1 Answer 1

10

Since the array here is a reference type, isn't reassigned during the operations, and isn't exposed elsewhere yet (where some other code could lock it), yes, it can suffice as the lock object itself. However, if the updates are to different parts of the array, i.e.

array[i] = ... // i is separate

then there is no need to lock anything.

Sign up to request clarification or add additional context in comments.

2 Comments

Many thanks for a very clarifying answer, Mark. In my specific scenario I am using Array.Copy() to write data to array, but each i thread touches its own "slot" of array. Given this, is it still OK to skip locking altogether?
@AndersGustafsson I can't think of any reason that would be a problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.