Quick Locking Question

  • Thread starter Thread starter Cool Guy
  • Start date Start date
C

Cool Guy

From http://www.yoda.arachsys.com/csharp/threads/volatility.shtml :

| We've already seen how locking is used to limit access to a
| single thread at a time. It also has another side effect: a
| call to Monitor.Enter performs an implicit volatile read,
| and a call to Monitor.Exit performs an implicit volatile write.

Which reads and writes, within a C# lock, are volatile? All of them? Just
the first?
 
Cool Guy said:
From http://www.yoda.arachsys.com/csharp/threads/volatility.shtml :

| We've already seen how locking is used to limit access to a
| single thread at a time. It also has another side effect: a
| call to Monitor.Enter performs an implicit volatile read,
| and a call to Monitor.Exit performs an implicit volatile write.

Which reads and writes, within a C# lock, are volatile? All of them? Just
the first?

Acquiring the lock is a volatile read, and releasing the lock is a
volatile write. That means that any reads you make during the lock will
definitely be up-to-date with respect to the state of memory before the
lock was acquired, and any writes you make during the lock will have
been made available to other threads before the lock is released.
 
Jon Skeet said:
Acquiring the lock is a volatile read, and releasing the lock is a
volatile write. That means that any reads you make during the lock will
definitely be up-to-date with respect to the state of memory before the
lock was acquired, and any writes you make during the lock will have
been made available to other threads before the lock is released.

So my understanding is that every read in a lock is volatile, and that
every write in a lock is also volatile.

But I don't understand the wording here: "Acquiring the lock is a volatile
read." A 'volatile read', to me, means a read of a volatile variable.

So I'm trying to work out what entity is being read (in a volatile fashion)
when one aquires a lock...
 
Cool Guy said:
So my understanding is that every read in a lock is volatile, and that
every write in a lock is also volatile.

No. There's nothing to say that all the writes inside the lock are
volatile. For instance, consider:

Thread 1:
lock (something)
{
someVariable = someValue;
Thread.Sleep(1000);
}

Thread2, executing during the sleep of the first thread:
lock (something) // Just for the sake of a volatile read
{
}
foo = someVariable;

There's nothing to guarantee that foo will have the value of someValue.
In other words, because the lock hasn't been released, the new value of
someVariable *may* not have been "published" as far as other threads
are concerned.
But I don't understand the wording here: "Acquiring the lock is a volatile
read." A 'volatile read', to me, means a read of a volatile variable.

Not necessarily - a read of a volatile variable *is* a volatile read,
but the term "volatile read" is more in terms of memory barriers and
what operations can be moved past that barrier.
 
that's really a terrible example theoretically unless somevariable is
related to something instance.

What would be the point of locking on an instance to set a totally unrelated
entity?

--
Regards,
Alvin Bruney - ASP.NET MVP

[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
Now available @ www.lulu.com/owc, Amazon.com etc
 
that's really a terrible example theoretically unless somevariable is
related to something instance.

Which indeed it would be. Usually it would be a private variable within
the same class as someVariable.
What would be the point of locking on an instance to set a totally unrelated
entity?

Assuming from your post that you would prefer lock(this), read
http://www.pobox.com/~skeet/csharp/threads/lockchoice.shtml for why I
believe *that's* a really terrible idea.
 
grmbl grmbl, grmbl...

interesting stuff.

well I already a mix of both.

I try to keep my atomic section short. if there is any risk of them being
long I usually bother create a private lock, so I don't create deadlock
unwillingly...

and I tend to also use the same lock for all operation on 1 object, wether
it being this or a private lock
 
No, i wasn't suggesting lock(this). I am familiar with the lock(this) issues
already.

So what's the problem? I usually use specific private variables which
are *only* used for locking purposes, rather than locking on other
references. That way, I can be absolutely sure that no-one else is
going to lock on those references at the same time - not even methods
within the objects being referenced.
 
Back
Top