1

In my C# program, I have got method code:

Object model;
int score;
for()
{
    int tempScore=0;
    Object tempModel=getModel();
    //some interesting stuff modifying value of tempScore
    if(tempScore>score)
    {
        score=tempScore;
        model=tempModel;
    }
}

I would like to use Parallel for insted of normal, but I'm afraid that i will encounter some synchronization issues. I know that I can use lock(model), but what can I do about simple type score? model and score are method local variables, therefore they are shared between threads.

Alex
  • 887
  • 1
  • 11
  • 29
Skiba
  • 440
  • 1
  • 6
  • 17
  • The snippet isn't clear enough. Consider thread-local variables. The essential how-to article is here: http://msdn.microsoft.com/en-us/library/dd460703.aspx – Hans Passant May 19 '12 at 20:36
  • We need to know which variables are shared between threads. We can guess that `score` is shared. You can use thread local scores in a map/reduce algorithm. Or you could use interlocked operations. Or locking. – David Heffernan May 19 '12 at 20:41

1 Answers1

2

If you use lock (model), it doesn't mean that other threads won't be able to access model. What it means is that two threads won't be able to execute a section protected by lock (model) at the same time. Because of this, you could use something like lock (model) to protect access to score too.

But that wouldn't work in this case. lock doesn't lock on a variable, it locks on an object and you modify which object model refers to in the loop. Because of that, I thin the best option here is to create another object and lock on that:

object model;
int score;
object modelLock = new object();

Parallel.For(…, (…) =>
{
    int tempScore=0;
    Object tempModel=getModel();
    //some interesting stuff modifying value of tempScore
    lock (modelLock)
    {
        if(tempScore > score)
        {
            score=tempScore;
            model=tempModel;
        }
    }
});

If you find out that this is too slow for your needs (because using lock does have some overhead, which might be significant for you), you should consider using something like Thread.VolatileRead() or Interlocked.CompareExchange(). But be very careful with them, because it's very easy to make your code subtly wrong.

svick
  • 236,525
  • 50
  • 385
  • 514
  • Thanks, a lot! Looks like VolatileRead was exactly what I was looking for, and it works! – Skiba May 20 '12 at 22:36