Threading newbie: Lock statement

J

Jan

Hi Group,

Does the "lock" statement lock the "ressource" or the code section (like a
critical section)?

Let me elaborate: I have two threads accessing the same ressource, but from
*different* parts of the code. Can I use the lock statement to synchronise
access, or can I only use lock when the threads access the ressource from
the *same* part of he code (critical section). MSDN is somewhat unclear
about this.

The following simplified code sample illustrates the problem:

// Imagine I have Thread1 executing only MyFirstThreadProcedure() a 1000
times.
// At the same time I have Thread2 executing on MySecondThreadProcedure() a
1000 times.
class Class1 {
static int counter;
public static void MyFirstThreadProcedure()
{
lock (counter) { counter++; }
}
public static void MySecondThreadProcedure()
{
lock (counter) { counter += 2; }
}
}

The code sample above works, but I have only tried this on a uniprocessor
machine.

(Let me know if I have formulated my question in an unclear way)

Kind Regards
Jan
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Jan said:
Does the "lock" statement lock the "ressource" or the code section (like a
critical section)?

Let me elaborate: I have two threads accessing the same ressource, but from
*different* parts of the code. Can I use the lock statement to synchronise
access, or can I only use lock when the threads access the ressource from
the *same* part of he code (critical section). MSDN is somewhat unclear
about this.

You can lock on the same object from different code
and achieve the desired synchronization.

But remember - it is still 100% cooperative locking.

Arne
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Jan said:
Does the "lock" statement lock the "ressource" or the code section (like a
critical section)?

Actually neither. It's creating a Monitor with the object reference as
key. If some other thread tries to create another Monitor using the same
object, it will not be allowed to proceed until the first Monitor is
released.
Let me elaborate: I have two threads accessing the same ressource, but from
*different* parts of the code. Can I use the lock statement to synchronise
access, or can I only use lock when the threads access the ressource from
the *same* part of he code (critical section). MSDN is somewhat unclear
about this.

It doesn't matter where the code is, the only thing that matters is that
you use the same object in the lock statements.

....something that you failed to do in your example:
The following simplified code sample illustrates the problem:

// Imagine I have Thread1 executing only MyFirstThreadProcedure() a 1000
times.
// At the same time I have Thread2 executing on MySecondThreadProcedure() a
1000 times.
class Class1 {
static int counter;
public static void MyFirstThreadProcedure()
{
lock (counter) { counter++; }
}
public static void MySecondThreadProcedure()
{
lock (counter) { counter += 2; }
}
}

The code sample above works, but I have only tried this on a uniprocessor
machine.

No, it doesn't work.

An integer is not a reference type, so you will be locking on a boxed
copy of the value. The locking statements have no effect what so ever,
as you will be locking on a newly created object every time.

You have to create an object that you can use for locking. Example:

static object counterLock = new Object();
static int counter = 0;

public static void MyFirstThreadProcedure() {
lock (counterLock) { counter++; }
}

public static void MySecondThreadProcedure() {
lock (counterLock) { counter += 2; }
}

As you see, the object that you are locking on doesn't need to have
anything to do with the actual data that you handle inside the lock.
 
G

Guest

As an aside, the code from the OP should not even compile, since implicit
boxing is not performed for the expression used in a lock statement, so
having a value type as the lock expression will cause a compilation error.

Mark.
 
J

Jan

Thought so, but I had to make sure. Figure that there's probably a Mutex
somewhere deep down.

Thanks a million.

- Jan
 
J

Jan

Oops, you got me. My apologies. To be honest I didn't test; I wrote it in
notepad just to illustrate the problem. (In my *real* code, where it works,
I of course have a reference type).

But apart from that, thanks for the answer. It was exactly the answer I was
hoping for. I suppose somewhere deep down it ends up with a mutex, so it
doesn't really matter what you are trying to lock, as long as it ends up
with the same mutex.

- Jan
 
J

Jan

Gee, there's no cheating you guys. I'll be more careful in the future when
writing samples ;o)

Thanks for the reminder
- Jan
 
J

Jon Skeet [C# MVP]

Jan said:
Thought so, but I had to make sure. Figure that there's probably a Mutex
somewhere deep down.

Well, there's a conceptual mutex - but I don't believe it uses a Win32
Mutex. The .NET locking is only within a single process, and is lighter
weight than using a Mutex.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top