Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explain the code: c# locking feature and threads

I used this pattern in a few projects, (this snipped of code is from CodeCampServer), I understand what it does, but I'm really interesting in an explanation about this pattern. Specifically:

  1. Why is the double check of _dependenciesRegistered.
  2. Why to use lock (Lock){}.

Thanks.

public class DependencyRegistrarModule : IHttpModule
{
    private static bool _dependenciesRegistered;
    private static readonly object Lock = new object();

    public void Init(HttpApplication context)
    {
        context.BeginRequest += context_BeginRequest;
    }

    public void Dispose() { }

    private static void context_BeginRequest(object sender, EventArgs e)
    {
        EnsureDependenciesRegistered();
    }

    private static void EnsureDependenciesRegistered()
    {
        if (!_dependenciesRegistered)
        {
            lock (Lock)
            {
                if (!_dependenciesRegistered)
                {
                    new DependencyRegistrar().ConfigureOnStartup();
                    _dependenciesRegistered = true;
                }
            }
        }
    }
}
like image 891
Fitzchak Yitzchaki Avatar asked Apr 29 '10 21:04

Fitzchak Yitzchaki


People also ask

What is meant by code C?

Coding in C refers to the logic implemented over the program using its derivative.

How does C code works?

The C programming language works by writing your code into an executable file. The C compiler will take that executable and convert it in its entirety into machine code that will then be executed by your computer at runtime.

What is basic C concept?

What is C? 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

This is the Double-checked locking pattern.

The lock statement ensures that the code inside the block will not run on two threads simultaneously.
Since a lock statement is somewhat expensive, the code checks whether it's already been initialized before entering the lock.
However, because a different thread might have initialized it just after the outer check, it needs to check again inside the lock.

Note that this is not the best way to do it.

like image 88
SLaks Avatar answered Oct 05 '22 12:10

SLaks


The double-check is because two threads could hit EnsureDependenciesRegistered at the same time, both find it isn't registered, and thus both attempt to get the lock.

lock(Lock) is essentially a form of mutex; only one thread can have the lock - the other must wait until the lock is released (at the end of the lock(...) {...} statement).

So in this scenario, a thread might (although unlikely) have been the second thread into the lock - so each must double-check in case it was the second, and the work has already been done.

like image 29
Marc Gravell Avatar answered Oct 05 '22 12:10

Marc Gravell