Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to prevent a deadlock when you need to lock multiple objects

Tags:

c#

Image this code:

You have 2 arrays, and you need to lock both of them in same moment (for any reason - you just need to keep locked both of them because they are somehow depending on each other) - you could nest the lock

lock (array1)
{
    lock (array2)
    {
        ... do your code
    }
}

but this may result in a deadlock in case that someone in other part of your code would do

lock (array2)
{
    lock (array1)
    {
        ... do your code
    }
}

and array 1 was locked - execution context switched - then array 2 was locked by second thread.

Is there a way to atomically lock them? such as

lock_array(array1, array2)
{
    ....
}

I know I could just create some extra "lock object" and lock that instead of both arrays everywhere in my code, but that just doesn't seem correct to me...

like image 813
Petr Avatar asked Dec 26 '22 03:12

Petr


2 Answers

In general you should avoid locking on publicly accessible members (the arrays in your case). You'd rather have a private static object you'd lock on.

like image 91
Darin Dimitrov Avatar answered May 10 '23 17:05

Darin Dimitrov


You should never allow locking on publicly accessible variable as Darin said. For example

public class Foo
{
    public object Locker = new object();
}

public class Bar
{
    public void DoStuff()
    {
        var foo = new Foo();
        lock(foo.Locker)
        {
            // doing something here
        }
    }
}

rather do something like this.

public class Foo
{
    private List<int> toBeProtected = new List<int>();
    private object locker = new object();

    public void Add(int value)
    {
        lock(locker)
        {
            toBeProtected.Add(value);
        }
    }
}

The reason for this is if you have multiple threads accessing multiple public synchronization constructs then run the very real possiblity of deadlock. Then you have to be very careful about how you code. If you are making your library available to others can you be sure that you can grab the lock? Perhaps someone using your library has also grabbed the lock and between the two of you have worked your way into a deadlock scenario. This is the reason Microsoft recommend not using SyncRoot.

like image 29
uriDium Avatar answered May 10 '23 17:05

uriDium