Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Lock statements

When a thread tries to enter a critical section and obtain a lock, what is it actually doing?

I'm asking this because I usually create an object (of type object) which will serve for locking purposes only. Consider the following: I want to write a method which accepts a collection, and an object which will serve as the locking object so the whole collection manipulation inside that method will be declared inside the critical section which will be locked by that given object.

Should I pass that locking object using "ref" or is passing a reference copy of that object is enough? In other words - since the lock statement is used with reference types only, does the mechanism check the value of the referenced object, or does it check the pointer's value? because obviously, when passing an object without "ref", I actually get a copy of the reference, and not the reference itself.

like image 393
Mikey S. Avatar asked Aug 14 '11 13:08

Mikey S.


People also ask

What C is used for?

C is a powerful general-purpose programming language. It can be used to develop software like operating systems, databases, compilers, and so on.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

What is C in coding language?

C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.


2 Answers

Here's a typical pattern that you can follow for locking. Basically, you can create a locking object that is used to lock access to your critical section (which, as @Hans said, is not protecting the object that you're working on -- it just handles the lock).

class ThreadSafe
{
  static readonly object _locker = new object();
  static int _val1, _val2;

  static void Go()
  {
    lock (_locker)
    {
      if (_val2 != 0) Console.WriteLine (_val1 / _val2);
      _val2 = 0;
    }
  }
}

This example was from Joseph Albahari's online book on threading. It provides an excellent overview of what's going on when you create a lock statement and some tips/tricks on how to best optimize for it. Definitely highly recommended reading.

Per Albahari, again, the lock statement translates in .NET 4 as:

bool lockTaken = false;
try
{
  Monitor.Enter (_locker, ref lockTaken);
  // Do your stuff...
}
finally { if (lockTaken) Monitor.Exit (_locker); }

It's actually safer than a straight Monitor.Enter and then calling Monitor.Exit in your finally, which is why it was added in .NET 4.

like image 78
David Hoerster Avatar answered Oct 13 '22 04:10

David Hoerster


It's enough to lock the object without passing ref. What lock actually does is, call Monitor.Enter on the beginning of the block and Monitor.Exit on exit.

Hope this helps.

like image 42
Tigran Avatar answered Oct 13 '22 03:10

Tigran