C# Best Practice: Why a Separate “lock” Object?

Reading Time: 4 minutes

Some time about 1995 I noticed that I was writing a lot more concurrent code than the other programmers. It was almost as if someone was deliberately pushing it in my direction… That theme never really changed.

I was rather surprised then when a developer made a comment on something I’d written a few years back, because I was pretty confident I’d covered all the bases.

public class SomeServer
{
    private readonly Dictionary<KeyType, ValueType> queries = new Dictionary<KeyType, ValueType>();

    //stuff

    public void PerformLookup(string someQueryTerm)
    {
        //some logic...
        lock(queries)
        {
            //some more logic
        }
    }
}

The comment was:

Please use a separate lock object. e.g. private readonly object _queriesLock = new Object();

Eh? What?

OK, hands up I missed this. I learnt to use basic concurrency tools way before C# existed. For me C#’s ‘lock’ construct was great because it allowed me a very clear and concise way to use a monitor. As far as I was concerned there was no downside. Why on earth would I want to use a separate lock object?

There are 2 things you need to be really careful about when using a lock in this way.

You must carefully manage the lifetime of the locked object.

Imagine above if ‘queries’ were not a readonly object created at instance initialisation. Imagine if someone did…

lock(queries)
{
    //stuff
    queries = new Dictionary<KeyType, ValueType>();
}

You have to make sure that the locked object is instantiated before the fist lock is taken out and you must make sure that it is not reassigned in any way until after the last lock has been exited.
If you don’t it leads to all different flavours of bad.

If you instantiate a separate lock object at object initialisation, an object that has no purpose other than as a lock, then you know it’s there at the start and the chances of someone messing with it before the end of the last lock are very significantly reduced.

You must be careful not to expose the locked object externally

C# allows an implicit monitor to be created on any object. You can use that monitor by wrapping the object in a ‘lock’ statement.

If you wrote the class to use, say a mutex explicitly rather than the implicit monitor there’s no way you consider making the mutex externally accessible…

public class SomeServer
{
    private readonly Dictionary<KeyType, ValueType> queries = new Dictionary<KeyType, ValueType>();
    public Mutex _queryLock = new Mutex();

    //stuff

    public void PerformLookup(string someQueryTerm)
    {
        //some logic...
        _queryLock.WaitOne();
        try
        {
            //some more logic
        }
        finally
        {
            _queryLock.ReleaseMutex();
        }
    }
}

That’s complete madness – any other class can mess directly with the lock and cause all sorts of unwanted behaviour. Deadlocks are a particular hazard here and compound deadlocks can be really tough to debug.

If you’re using the implicit monitor via the ‘lock’ construct however and you expose the locked object beyond the scope of the class, you are effectively also sharing the monitor.

public class SomeServer
{
    public Dictionary<KeyType, ValueType> queries {get; private set;} = new Dictionary<KeyType, ValueType>();

    //stuff

    public void PerformLookup(string someQueryTerm)
    {
        //some logic...
        lock(queries)
        {
            //some more logic
        }
    }
}

public class SomeOtherClass
{
    private SomeServer myServer=new SomeServer();

    public void SomeMethod()
    {
        lock(myServer.Queries)
        {
            //some logic
        }

        //or worse...
        Monitor.Enter(myServer.Queries)
        //and the Monitor.Exit is in another method that might not get called
    }
}

If you use a separate lock object that you know is private and will always be private then you don’t have to worry about this.

Having written this pattern many, many times in many different languages I’m not likely to fall into either trap. That’s not all that being a good developer is about though.

HwacheonCentreLathe 460x1000

Now, this might seem like a strange tangent but bear with me. I learnt to use an industrial [machine] lathe when I was a kid. They teacher drummed 2 things into us.

  1. Do not wear any loose clothing (e.g. a tie)
  2. Do not leave the chuck key in when starting the lathe

The reason these 2 things in particular were so important was because the lathe I learnt to use had no guard. Either of those 2 mistakes could be fatal.

I’m glad I learnt that, but given the choice would I use the lathe with a guard or the one without? It’s a no-brainer.

We have the same situation here. Unless we’re writing something very specific where memory is absolutely critical, there’s no harm in creating an extra lock object. It provides a useful safeguard against a couple of gotchas that could cause real headaches in production.

Software development purists will be wringing their hands, but they’re not what commercial software development is about. It’s about writing code that does the job in a simple, safe and maintainable way. That’s why using a separate lock object is C# best practice and that’s why I fully support it.

Intlerocked.Exhange and the Atomic Option

Reading Time: 4 minutes

Developers are now having to deal with concurrency issues far more than we ever have in the past. Our languages are evolving more and more features (like the Parrallel.* class in C#) that allow us to take advantage without too much pain.
These are great, but they’re not always the answer and they don’t negate the need to understand the fundamental issues of concurrent programming. This is in fact the very subject that this blog started with several years ago...

Today I’d like to talk about Interlocked.Exchange. Its purpose it to exchange two variables in an atomic way. It’s the atomic nature of the exchange that’s the important factor here, it means that nothing can catch the exchange in an incomplete state. It’s either completely one value or completely another value.

Thread Safe Exchange

The significance of this becomes evident when we consider the traditional method of exchanging two variables.

var spare = first;
first = second;
second = spare;

This is not thread safe. The problem is that a second thread could interleave into the first. Consider the following path of execution. Let’s assume the value of first is 5 and the value of second is 10. The table shows the values of the variables as two threads interleave.

Thread Code first second spare 1 spare 2
1 var spare = first; 05 10 05
1 first = second; 10 10 05
2 var spare = first; 10 10 05 10
1 second = spare; 10 05 05 10
2 first = second; 05 10 05 10
2 second = spare; 05 10 05 10

Oh dear… that didn’t work, did it?

If we’d used Interlocked.Exchange we wouldn’t have the problem, because the exchange is atomic no interleaving can take place, the first thread will finish then the second will take over.

Thread Safe Changes of Scope

When it gets really interesting though is the fact that Interlocked.Exchange returns the original value.

public static T Exchange(
    ref T location1,
    T value)
    where T : class

The beauty of this is that we can use this to change scope. There’s a wholly unsafe pattern that gets used in Dispose handlers all the time:


class Blah: IDisposable
{
    SomeDisposableType someObject;

    ...

    public void Dispose()
    {
        if(someObject != null)
        {
           someObject.Dispose();
           someObject = null;
        }
    }
}

It’s possible that two threads could interleave between the null check and someObject being assigned to null, resulting in someObject being disposed twice.

Alternatively…

public void Dispose()
{
    var myCopy = Interlocked.Exchange(ref someObject, null);
    if(myCopy != null)
    {
        myCopy.Dispose();
    }
}

What the Interlocked.Exchange does here is to set someObject to null in the object scope and return its (former) value to myCopy which is in the method scope.
If two threads call Dispose at exactly the same moment, then both of them will succeed in setting the value of someObject to null. In the case of the thread that calls Interlocked.Exchange first, it will return the original value of someObject to its myCopy and set someObject to null. When the second thread calls Interlocked.Exchange it will return the value that the first thread set someObject to, that being null. It will then proceed to set someObject to null again.
The effective is that someObject is set to null twice, but only one of the threads gets the original value of someObject, so only one will pass the null check and only one will call Dispose on someObject.

Note that this isn’t a good Dispose pattern fullstop however. Microsoft have written some guidelines.

This scope switching trick can be useful in other places too. Consider if you’re writing a log file of some description. Writing an ever-expanding log file causes problems, it’s good to have a cut-off and write a new one every so often. A common method is to write one file per day of the week.

public class LogWriter : IDsiposable
{
    StreamWriter writer;
    public string FilePath {get;set;}
    ...

    public void WriteLog(string s)
    {
        writer.WriteLine(s);
    }

    public void StartNewDaysLog()
    {
        var newWriter = new StreamWriter(FilePath + DateTime.Now.DayOfWeek.ToString() + ".log", false);
        var oldWriter = Interlocked.Exchange(ref writer, newWriter);
        if(null != oldWriter)
            oldWriter.Close();
    }
    ...
}

With this implementation multiple threads can safely call WriteLog continuously. When StartNewDaysLog is called a new StreamWriter is set up ready to go, then the two are switched in an atomic fashion. Nothing can catch this out half way through the switch – as far as anything calling WriteLog is concerned one entry was written to one file and the next to another: it’s seamless.
After the switch, StartNewDaysLog is left with the old StreamWriter which it then has to Close (which in turn calls Dispose).

Conclusion

Interlocked.Exchange is a surprisingly useful little tool. Its plain usage – to simply exchange a value in a thread safe way is useful, but where it really comes in handy is in its ability to replace a value and return the original one into a narrower (thread safe) scope. This is particularly handy if you need to move or consume something in a simple way that doesn’t imply graduating to a mechanism such as ReaderWriterLockSlim or SemaphoreSlim.

C#’s Parallel.Invoke is [Insert Hyperbole Here]

Reading Time: 2 minutes

Freeside VTIt’s simple – we can’t make processors go any faster. But we can add more cores.
The OS can schedule different processes to different cores but to take full advantage of the potential we need to be writing applications that run on multiple cores.
Unsurprisingly there’s a lot of investment in making this easier for programmers – to the point that it’s now easier than falling off a log…

Parallel.Invoke(
    () =>
    {
        if (!GetSomethingFromTheDb(out something))
            something = MakeUpSomethingFromSomewhere();
    },
    () =>
    {
        complexResult = SomeComplexOperation();
    },
    () =>
    {
        someObjectGraph = ReadAndParseSomeFile(fileName);
    });
SomeReallyComplexThing(something, complexResult, someObjectGraph);

The individual actions will be run in parallel, or to be more precise may be run in parallel. The task scheduler takes care of whether or not to actually run them in parallel and the degree of parallelism.

When we arrive at SomeReallyComplexThing all the previous tasks will have been done.

That’s ace. It’s a lot easier than messing about with threads.

Even before the Parallel library was around it wasn’t actually difficult, but you needed some lateral thinking…

Task[] tasks = new Task[] {
    Task.Factory.StartNew(()=>
    {
        if (!GetSomethingFromTheDb(out something))
            something = MakeUpSomethingFromSomewhere();
        }),
    Task.Factory.StartNew(()=>
    {
        complexResult = SomeComplexOperation();
    }),
    Task.Factory.StartNew(()=>
    {
        someObjectGraph = ReadAndParseSomeFile(fileName);
    })
};
Task.WaitAll(tasks);
SomeReallyComplexThing(something, complexResult, someObjectGraph);

Ok, I admit, I’m simplifying. You still need to understand the basic problems of concurrent programming but the mechanics of writing code that can take advantage of parallelism are now trivial.

The Art of Making Multithreading Issues Worse

Reading Time: 3 minutes
It also took me ages to find that these were dead

I recently spent days looking for a bug – a thread safety bug – that I should have found in minutes. The reason it took so long is that someone had found it before me and attempted to fix it, twice, but each time had in fact made matters worse.

What made matters even worse than that is a phenomenon that will be all too familiar to you if you handle multithreaded code a lot – the customer could make it happen every time but on the bench, back at the office with all the debug tools? Practically impossible to reproduce.

So the code started off like this, and here I’ve extracted the essence of the problem, this is not the real code. In reality the mistake was the same, but heavily obfuscated right from the start.

class AlarmManager
{
    private Dictionary alarms = new Dictionary();

    public Guid StartAlarm()
    {
        Alarm newAlarm = new Alarm();
        newAlarm.AlarmId = Guid.NewGuid();
        alarms.Add(newAlarm.AlarmId, newAlarm);
        newAlarm.AlarmWorkflow = WorkflowManager.CreateAlarmWorkflow(newAlarm.AlarmId);
        return newAlarm.AlarmId;
    }

    public void DeleteAlarm(Guid alarmId)
    {
        Alarm toRemove;
        if (alarms.TryGetValue(alarmId, out toRemove))
        {
            toRemove.AlarmWorkflow.StopAndRemove();
            alarms.Remove(alarmId);
        }
    }
}

Two schoolboy errors in there. Someone spotted the first, Dictionaries are not thread safe, so they added some locking…

class AlarmManager
{
    private Dictionary alarms = new Dictionary();

    public Guid StartAlarm()
    {
        Alarm newAlarm = new Alarm();
        newAlarm.AlarmId = Guid.NewGuid();
        lock (alarms)
        {
            alarms.Add(newAlarm.AlarmId, newAlarm);
        }
        newAlarm.AlarmWorkflow = WorkflowManager.CreateAlarmWorkflow(newAlarm.AlarmId);
        return newAlarm.AlarmId;
    }

    public void DeleteAlarm(Guid alarmId)
    {
        Alarm toRemove;
        lock (alarms)
        {
            if (alarms.TryGetValue(alarmId, out toRemove))
            {
                toRemove.AlarmWorkflow.StopAndRemove();
                alarms.Remove(alarmId);
            }
        }
    }
}

Fixed? No. This is where we hit the real problems. Someone noticed that the line toRemove.AlarmWorkflow.Stop(); was throwing null reference exceptions, so rather than investigate how toRemove.AlarmWorkflow came to be null they simply put a null check in…

public void DeleteAlarm(Guid alarmId)
{
    Alarm toRemove;
    lock (alarms)
    {
        if (alarms.TryGetValue(alarmId, out toRemove))
        {
            if (toRemove.AlarmWorkflow != null)
                toRemove.AlarmWorkflow.StopAndRemove();
            alarms.Remove(alarmId);
        }
    }
}

The reason it was occasionally null is in StartAlarm. That’s where the bug is – the new alarm is added to the dictionary and the lock released before it’s finished initialising. So if it’s deleted by another thread immediately after it’s started, the threads can interleave in a way where the alarm is removed from the dictionary with the workflow being null, then the workflow is assigned and started. As the workflow is managed by the WorkflowManager, there’s still a reference to it, hence it continues to run.

Now the issue got compounded further, because someone spotted that exceptions were still being thrown during the delete, from the StopAndRemove method. This is where my simplification falls down a bit because the real reasons for the exception are somewhat complex involving events and another access to the alarms dictionary, suffice to say however that this was not the way to solve the problem…

public void DeleteAlarm(Guid alarmId)
{
    Alarm toRemove;
    lock (alarms)
    {
        if (alarms.TryGetValue(alarmId, out toRemove))
        {
            try
            {
                if (toRemove.AlarmWorkflow != null)
                    toRemove.AlarmWorkflow.StopAndRemove();
            }
            catch 
            {
            }
            alarms.Remove(alarmId);
        }
    }
}

These two attempted fixes are part of a mindset of patching it up rather than fixing the root cause. In certain extreme circumstances patching it up may be acceptable. I’ve had to do it, but it must be highlighted that this is what has been done and that it may actually be masking the root cause or indeed causing further knock-on issues.
I find the #warning preprocessor directive useful in such circumstances.

The solution is trivial…

class AlarmManager
{
    private Dictionary alarms = new Dictionary();

    public Guid StartAlarm()
    {
        Alarm newAlarm = new Alarm();
        newAlarm.AlarmId = Guid.NewGuid();
        lock (alarms)
        {
            newAlarm.AlarmWorkflow = WorkflowManager.CreateAlarmWorkflow(newAlarm.AlarmId);
            alarms.Add(newAlarm.AlarmId, newAlarm);
        }
        return newAlarm.AlarmId;
    }

    public void DeleteAlarm(Guid alarmId)
    {
        Alarm toRemove;
        lock (alarms)
        {
            if (alarms.TryGetValue(alarmId, out toRemove))
            {
                alarms.Remove(alarmId);
                toRemove.AlarmWorkflow.Stop();
            }
        }
    }
}

Semaphores and Message Passing

Reading Time: 5 minutes

A really great way of signalling between ships. If your radio has failed, that is.

A little note: this article was written in 2010 – the principles of a semaphore haven’t changed in decades, but the code included is somewhat out of date now.

No, you’ll be glad to hear that Semaphores in computing don’t involve standing in a prominent position and waving your arms around like a lunatic. Semaphores are handy little constructs that are especially of use in producer / consumer scenarios, indeed this is by far the easiest way of explaining them. I find imagining the semaphore to be a person, a supervisor, to be the best way of visualising it. Every time one of the producers has some work it hands it to the supervisor. If there are no workers (consumers) waiting for work, the supervisor stores it until such time as one asks for more. The important thing about a semaphore is that if there are no work items, the supervisor makes the workers wait.

So, to the semaphore itself – they act most like accumulators, you increment and decrement them. Worker threads (consumers) try to decrement the semaphore. If the semaphore is already at zero and a thread tries to decrement it, that thread will wait. Producers increment the semaphore. It’s important to note that if multiple threads are waiting on a semaphore and the semaphore is then incremented by one, only one thread will be released. The rest will remain waiting. There’s a more real world example in the diagram beneath…

Semaphore and Queue

In said diagram there are several producers. When a producer has an item it always follows a strict sequence, it adds the item to the queue and then increments the semaphore. The consumer threads do the reverse, they know that if they can decrement the semaphore that they can safely take an item from the queue. Of course, if the semaphore drops to zero then consumer threads will have to wait until a producer increments the semaphore. At this time one consumer thread will be released to process the added work item.
There’s an example of this in action in this zip file (C#, VS2008), extract beneath.

static void Consumer()
{
    string item;
    int queueLength;
    do
    {
        mySemaphore.WaitOne(); // wait for an item to be available
        lock (myQueue) // queue isn't thread safe so we need to lock.
        {
            item = myQueue.Dequeue();
            queueLength = myQueue.Count;
        }
        if (!String.IsNullOrEmpty(item))
            Console.WriteLine(String.Format("C{0:00} DEQUEUE Q{1:00}: {2}",
        Thread.CurrentThread.ManagedThreadId, queueLength, item));
        Thread.Sleep(250);
    } while (!String.IsNullOrEmpty(item)); //we use null to signify end of processing
}

static void Producer()
{
    int queueLength;
    foreach (string line in Shelley)
    {
        Thread.Sleep(random.Next(1000));
        lock(myQueue) //queue isn't thread safe so we need to lock.
        {
            myQueue.Enqueue(line);
            queueLength = myQueue.Count;
        }
        mySemaphore.Release(); //let any waiting consumers go.
        Console.WriteLine(String.Format("p{0:00} enqueue Q{1:00}: {2} ",
        Thread.CurrentThread.ManagedThreadId, queueLength, line));
    }
}

Without semaphores, ensuring that the producer / consumer model works efficiently tends either to get very complex, or inefficient.

That’s really all there is to say about semaphores, apart from the fact that you shouldn’t limit your thinking about them to producer / consumer scenarios, they can actually come in surprisingly handy elsewhere.

Message Passing

Message passing is massively important in most of today’s GUI applications, yet it’s surprising the number of people who have no real idea what it’s about.
In order to understand message passing though really you need a basic understanding of what a thread actually is. It’s a procedure. Regardless of wrappers etc. when you create a thread what you actually say to the scheduler is “take this block of code and execute it in parallel with everything else I’m doing”. If you look at the code above you’ll notice two static methods; Producer and Consumer. These form the code block for threads – 2 copies of Producer and 3 of Consumer are run at the same time.
If they were a straight block of code, execution would fall off the end and the thread would end. Both however loop until some condition is met, when they stop.

It’s important if you do use loops in threads that there is some end condition so that they can stop when the program ends.

The main thread in the majority of GUI applications is exactly like this :- it actually runs a simple loop that waits for messages. When it gets a message, it performs some sort of action (usually calling a handler) and then returns to waiting for the next message. In this context a message is likely to be a mouse click, a key press or an instruction to minimise and these come from the operating system, but it could equally well be an instruction that we generate ourselves.

Why do we do it? Well in the case of most GUI apps it ensures that everything that happens to the GUI happens in one thread. If the handlers are well written, then every action starts with the GUI in a stable position and finishes leaving the GUI in a stable position.

We can look at it as a transaction processing system: transactions (messages) are serialised on the queue and each one is executed discretely.

All we need to do this ourselves is a thread that loops on some sort of queue, waiting for a message to arrive and some sort of message structure for it to process. This is an extremely powerful technique, but it isn’t without its hazards. As much as it can be used to aide thread safety by ensuring that access to data and resources is correctly sequenced, it can just as easily ruin thread safety, particularly as the exact time when a message is going to be processed cannot be known, therefore the lifetime and access to any data shared between threads must be very carefully considered.

Windows itself provides a standard framework for message passing that contains two fundamental ways of passing a message – PostMessage and SendMessage. No, the names are not brilliant. PostMessage puts and a message on the queue for the message processing thread and continues running. SendMessage by comparison puts a message on the queue for the message processing thread and then blocks the calling thread until the message has been processed.

In WPF we can look at the Dispatcher framework – that’s an easier to use version of the same thing.

If before I mentioned that last bit you hadn’t realised that Message Passing opens up a whole new world of pain when it comes to deadlocking, you should now. Imagine what happens if a handler in thread A does a SendMessage to thread B, which then tries to lock a resource that thread A has locked.

If you’re programming with message passing it’s more important than ever to ensure what state your data is in at any moment and what has access to it, but you must also keep on top of flow and make sure that deadlock situations can’t arise.

OK, I suspect I’m a little bit of a nerd about this, but I actually find it quite fun to look at designs and work out where the deadlocks can happen, but it’s from years of playing about with this that I understand exactly what is likely to happen and it why.

Next time I’ll start looking at how the constructs provided in C# and the .NET Framework 3.5 to help us with threading.

The Threading Series

Article 1: Threading: Get Up To Speed Now!

Article 2: Thread Safety: Why Local Variables Are Good

Article 3: Threading: Locking and Deadlocks Introduced

Article 4: Combating Simple Deadlocks and Semaphores

Article 5: Semaphores and Message Passing

Combating Simple Deadlocks

Reading Time: 4 minutesSo last time I left you with the horror of deadlocks. To recap, a deadlock is when two (or more) threads can’t continue because there’s no way that they can get the resources that they need. A simple deadlock can occur when two threads, let’s call them A and B, both require access to two locks, but lock them in different orders.

  1. Thread A locks resource 1
  2. Thread B locks resource 2
  3. Thread A tries to get a lock on resource 2 but can’t until Thread B unlocks it
  4. Thread B tries to get a lock on resource 1 but can’t until Thread A unlocks it.

Stage 4 of the above can never succeed because Thread A is waiting for Thread B already. They’re mutually locked out, or deadlocked.

One of the easiest things to say about avoiding deadlocks is that you should always lock the resources in the same order. This will indeed prevent deadlocks and it works really well in simple little examples, but when you’re elbows deep in a myriad of objects and there’s all sorts of stuff flying around it can be difficult to ensure that this actually happens. That doesn’t mean abandon the idea, indeed I would suggest attempting to make sure that it’s the case anyway, but it’s not always practical to ensure.

Let’s look at the savings and current account example again. This is how it was…

BankAccount currentAccount;
BankAccount savingsaccount;

void moveFromSavingsToCurrent(int amount)
{
    //we need to work with savings, so lock it
    lock(savingsAccount)
    {
        if(savingsAccount.Total>amount)
        {
            //we can proceed, but we don't want any inconsistencies so we now need
            //to lock currentAccount
            lock(currentAccount)
            {
                savingsAccount -= amount;
                currentAccount += amount;
            }
        }
    }
}

void moveFromCurrentToSavings(int amount)
{
    //we need to work with current, so lock it
    lock(currentAccount)
    {
        if(currentAccount.Total>amount)
        {
            //we can proceed, but we don't want any inconsistencies so we now need
            //to lock savingsAccount
            lock(savingsAccount)
            {
                currentAccount -= amount;
                savingsAccount += amount;
            }
        }
    }
}

We can actually fix this one really easily.


BankAccount currentAccount;
BankAccount savingsaccount;

void moveFromSavingsToCurrent(int amount)
{
    //we need to work with savings, so lock it
    lock(savingsAccount)
    {
        lock(currentAccount)
        {
            if(savingsAccount.Total>amount)
            {
                savingsAccount -= amount;
                currentAccount += amount;
            }
        }
    }
}

void moveFromCurrentToSavings(int amount)
{
    //we need to work with current, so lock it
    lock(savingsAccount)
    {
        lock(currentAccount)
        {
            if(currentAccount.Total>amount)
            {
                currentAccount -= amount;
                savingsAccount += amount;
            }
        }
    }
}

By taking the two locks out every time and always in the same order we prevent the deadlock, but now we’re always having to perform both locks, which will be a performance hit. Is there a better way?

Possibly, if we always need to lock both for every operation that we do then we could simply use one lock instead. In fact, simplifying the locking strategy is a great way to reduce the possibility of deadlocks and done well can actually improve performance. After all, the more locks there are, the more chance of a deadlock.

Another trick is to test locks, either with or without a timeout. In order to do this we need to move away from the simple lock statement and explicitly use a mutex or similar). In doing so we break out of the simple c# constructs into the world where we must know what we or doing, or it will hurt us.


Mutex m = new Mutex();
...
m.WaitOne();

try
{
access the required resources...
}
finally
{
m.ReleaseMutex();
}

Here’s the simple construct to using a Mutex. It’s an object in c# so we need to create it. We then call WaitOne() on it when we need to get the lock and we call ReleaseMutex() when we’re done. It’s always good to try to do this in a try…finally because the number of times a Mutex is acquired (with WaitOne()) must match the number of times it’s released (ReleaseMutex()). This may sound silly, but a thread can actually acquire a Mutex more than once, for instance in a recursive function. If an instance of that function threw an exception, it could leave the Mutex with more acquisitions than releases, which would be a problem and would cause an exception to be thrown when another thread attempted to acquire it. A thread must exit leaving all Mutex releases and acquisitions balanced.

Apart from that, it’s just like a lock. Our personal finance example again…

BankAccount currentAccount;
BankAccount savingsaccount;

Mutex accountMutex=new Mutex();

void moveFromSavingsToCurrent(int amount)
{
accountMutex.WaitOne();
try
{
if(savingsAccount.Total>amount)
        {
            savingsAccount -= amount;
            currentAccount += amount;
        }
}
finally
{
        accountMutex.ReleaseMutex();
}
}

void moveFromCurrentToSavings(int amount)
{
    accountMutex.WaitOne();
    try
    {
        if(currentAccount.Total>amount)
        {
            currentAccount -= amount;
            savingsAccount += amount;
        }
    }
    finally
    {
        accountMutex.ReleaseMutex();
    }
}

So what about this waiting for a timeout business? Well there are several overloads of WaitOne() which basically allow you to specify some sort of timeout. WaitOne() then returns a boolean, if the wait is succesful and the Mutex is acquired, WaitOne() will return true. If it fails and times out, WaitOne() will return false. Note that although you can use this to get you out of a deadlock, it’s a bit of a hack. Programming it properly in the first place is a better idea. In fact, the amount of error handling code that’s required to avoid nasty consequences may well be greater than the amount of code required to make it work properly in the first place.

I mentioned in my last also also that there is the phenomenon of the compound deadlock. This is the one that really gets programmers frustrated because a simple deadlock like the one in our savings account example is relatively easy to spot. In reality deadlocks can be long chains of events, the chances of which happening can be millions to one. Code that has run fine for years can suddenly start deadlocking one one machine. Why? Something very subtle with the timing has changed. Maybe an operating system change, maybe a new piece of hardware that just happens to cause the particular sequence of events in the particular order at the particular times. The worst thing is that there’s no stack trace, no debug. Often it can’t even be made to do it in the debug environment, the only place it will do it is at the customer site.

Nest time I’ll talk about semaphores and I may even get on to semaphores.
By the way, I’m intending to tidy these articles up, provide more examples and link them together a bit later.

The Threading Series

Article 1: Threading: Get Up To Speed Now!

Article 2: Thread Safety: Why Local Variables Are Good

Article 3: Threading: Locking and Deadlocks Introduced

Article 4: Combating Simple Deadlocks and Semaphores

Article 5: Semaphores and Message Passing

Threading: Locking and Deadlocks Introduced

Reading Time: 4 minutesSo in this article on thread safety I finally get to talk about locking. Why has it taken me until article 3 to talk about this? Well, it’s not quite as straightforward as it first appears. Firstly there’s more than one type of lock. Secondly, there are hazards and pitfalls. Picking the wrong locking strategy, or implementing it badly can cripple performance rather than improving it. Then there’s the deadlock, it’s positively evil twin the compound deadlock and I’ll not even mention deadlocks that also involve message passing.

But before I start complicating matters with tales of horror, let’s take it right back to basics. In the examples from article 1 (C#, VS2008), in the not thread safe project there’s a comment to the effect that, to make the program thread safe, all one has to do is uncomment a lock statement.

        public static void DoAddition(object obj)
        {
            int tempVal;
            Thread.Sleep(rand.Next(10));

            /*
             * All you have to do to make this thread safe is uncomment this lock statement
             * Try it!
             */
            //lock (threads)
            {
                tempVal = accumulator;

                //wastes some time simulating a complex calculation
                for (double f = double.MaxValue; f > double.Epsilon; f *= 0.5f) ;

                accumulator = tempVal + 1;
            }
        }

The C# lock statement is a great example of a simple mutual exclusion lock. What we’re saying with the lock statement is to take a named variable, in this case threads and apply a mutual exclusion lock to it. This lock is in place whilst the code in the block (between the curly braces) is running and ends when we leave that block. What is the effect of this? Well, it means that if another thread tries to place a lock on the same variable (e.g. threads) whilst we’re executing the code block, it will have to wait until the our code block has finished.

If we revisit our example from the first article where we managed to accidentally declare our love to Dave, but this time use a lock, we can see the effect. The first thread locks msg, the second thread attempts to jump in and use msg whilst the first is still working with it. But when it tries to “acquire the lock” it can’t and has to wait until the first thread has finished and “releases the lock”. It’s worth noting that if a third thread jumped in, it would also have to wait.

Diagram of a simple mutex operation
The lock statement saves the day

Remember though that there’s no psychic element to the lock statement, or mutexes in most languages. Let’s look at a producer / consume example.

Queue<WorkItem> workQueue=new Queue<WorkItem>();

...

void processQueue()
{
    bool weNeedToProcess = true;
    do
    {
        WorkItem itemToProcess;
        lock(workQueue)
        {
            weNeedToProcess = workQueue.Any();
            if(weNeedToProcess)
                itemToProcess = workQueue.Dequeue();
            else
                itemToProcess = null;
        }
        if(null != itemToProcess)
        {
             do some things...
        }
    }while(weNeedToProcess);
}

...

void someMethod()
{
    //we need to queue a workItem
    WorkItem newWorkItem = new WorkItem(someTask);
    workQueue.Add(newWorkItem);
}

The processQueue method runs in a background thread processing items of work which are put on the queue by other threads. The problem though, is that in someMethod was have forgotten to lock workQueue which means that it’s not thread safe. When we add an item to the queue, processQueue could be in the middle of taking an item off the queue and all sorts of things could go wrong.

Fixing this is easy…

void someMethod()
{
    //we need to queue a workItem
    WorkItem newWorkItem = new WorkItem(someTask);
    lock(workQueue)
    {
        workQueue.Add(newWorkItem);
    }
}

So that’s one danger. Now let me introduce on the Great Satan of all multithreading, the deadlock. It’s really quite easy to explain a simple deadlock, thread a needs a lock that thread b has got at the same time as thread b needs a lock that thread a has got. Let’s go back to our savings account and current (or checking) account scenario.

BankAccount currentAccount;
BankAccount savingsaccount;

void moveFromSavingsToCurrent(int amount)
{
    //we need to work with savings, so lock it
    lock(savingsAccount)
    {
        if(savingsAccount.Total>amount)
        {
            //we can proceed, but we don't want any inconsistencies so we now need
            //to lock currentAccount
            lock(currentAccount)
            {
                savingsAccount -= amount;
                currentAccount += amount;
            }
        }
    }
}

void moveFromCurrentToSavings(int amount)
{
    //we need to work with current, so lock it
    lock(currentAccount)
    {
        if(currentAccount.Total>amount)
        {
            //we can proceed, but we don't want any inconsistencies so we now need
            //to lock savingsAccount
            lock(savingsAccount)
            {
                currentAccount -= amount;
                savingsAccount += amount;
            }
        }
    }
}

This will cause any experienced multithreaded programmer to scream in horror. Why?
Let’s say an instance of moveFromSavingsToCurrent and moveFromCurrentToSavings are run simultaneously and they interleave like this…

  1. moveFromSavingsToCurrent acquires the lock on savingsAccount
  2. Meanwhile, moveFromCurrentToSavings acquires the lock on currentAccount
  3. moveFromSavingsToCurrent asks for the lock on currentAccount, but has to wait until the thread running moveFromCurrentToSavings has finished with it.
  4. moveFromCurrentToSavings asks for the lock on savingsAccount, but has to wait until the thread running moveFromSavingsToCurrent has finished with it.

moveFromSavingsToCurrent can’t continue until moveFromCurrentToSavings releases the lock on currentAccount. The problem is that moveFromCurrentToSavings can’t progress and therefore can’t release its lock on currentAccount because it’s waiting for access to savingsAccount, which moveFromSavingsToCurrent has. These two threads will sit there doing nothing until they’re killed. That will probably be the end of your application, when the user finally gets irritated enough to forcibly close it.

Let’s have a go at diagramming that…

Diagram of a simple deadlock
A Simple Deadlock

I’m not sure that makes it any clearer but often seeing information presented in different ways suddenly makes it click.

Next time I’ll talk about avoiding simple deadlocks and introducing the real big hitter in the stakes of debugging hell, the compound deadlock.

The Threading Series

Article 1: Threading: Get Up To Speed Now!

Article 2: Thread Safety: Why Local Variables Are Good

Article 3: Threading: Locking and Deadlocks Introduced

Article 4: Combating Simple Deadlocks and Semaphores

Article 5: Semaphores and Message Passing

Thread Safety: We Love Local Variables!

Reading Time: 4 minutesSo I left you hanging last time. I teasingly introduced three things you can do to combat thread safety problems and then didn’t adequately explain any of them. Let’s start putting that right. First I’m going to explain more about why local variables are (usually) thread safe.

The really important thing to get your head round is the difference between value types and reference types. If a variable is an instance of a value type this means that when the CPU wants to work with it, it can access the value directly. Say we have an int, that’s a value type. When the CPU wants to work with an int it can just look at it and see the value.

If it is a reference type though, the CPU can’t access the value directly, instead what it can see is a reference to where the value is held. It can then go and get the value.

Objects are always reference types.

To demonstrate, if we have a class…

class snaf
{
    public void kung()
    {
        int foo = 10;
        ComplexObject bar;

        do some things...

        bar = new ComplexObject();
        cookTheBooks(foo, bar);

        do some other things...

        return;
    }
}

When we call the method kung, the variable foo and an empty reference to bar are created locally. int is a value type, whereas ComplexObject is a reference type.

Moving on a stage, we create an instance of ComplexObject and put a reference to in in bar. The actual memory used to store the new CompexObject is not local, but on the heap (which is just a big pile of memory that we have access to). After this we call another method and pass these two variables (foo and bar) in. Now we will be able to see the importance of the difference between reference types and value types, and passing by reference and passing by value.

So we call the method cookTheBooks


private void cookTheBooks(int foo, ComplexObject bar)
{
    foo++;
    bar.Total=bar.Total*cookFactor;
    return;
}

What will happen when we return from this method back to kung? When we passed in foo it was 10. You might be surprised to know that the value of foo will still be 10, but the value of bar. Total will be 11 times what it previously was.
How? Well foo is a value type, so it was passed by value. This means that the instance of foo in cookTheBooks was actually a copy of the original foo. This means that when cookTheBooks incremented foo, it only incremented a copy of foo, not the original. When cookTheBooks returned its copy of foo was discarded and we were left in the method kung with the original foo, value still in tact.
In contrast, bar is a reference type. When we passed this to cookTheBooks what we actually passed was a copy of the reference. Spot the problem? A copy of the reference points to precisely the same location in memory as the original. So when we modify bar.Total we are modifying the original. Hopefully this diagram will make it a little clearer.

Values vs. References

We can actually choose to pass a value type by reference (in C# by using the ref keyword). When we do this the method is not passed a copy, instead it is passed a reference to the original and any changed made in the method will change the original.

If we’d done this when we passed foo to cookTheBooks, when we incremented foo we would have incremented the original.


    ...
    cookTheBooks(ref foo, bar);
    return;
}

private void cookTheBooks(ref int foo, ComplexObject bar)
{
    foo++;
    bar.Total=bar.Total*cookFactor;
    return;
}

But we don’t want to do that here! We’ll stick to the original pass by value version.
So how does this rather long and complicated explanation affect thread safety? Well, every time kung is run, a new foo and a new reference to bar are created. Unless we explicitly pass foo by reference to something else, it’s inherently thread-safe. Nothing else can get to it.
To re-iterate – every instance of a value type that we create in a method is thread safe unless we explicitly pass it be reference somewhere else.
Member variables, even if they’re private value types, are not thread safe. If your object is used in multiple threads you have to deal with thread safety yourself.
As a reference type, bar‘s thread safety is not so straightforward. If it’s a simple object and we don’t pass it to anything, then as we have the only reference to it it must be thread safe. However, if bar is not a simple object, maybe a singleton, or maybe something that uses certain types of system resources, it might not be thread safe itself. So we have to be very careful about the assumptions we make with bar.

What impact does this have on the way we program? Well, it’s about scope. Consider this implementation…

class snaf
{
    private int foo = 10;

    public void kung()
    {
        ComplexObject bar;
        do some things...
        bar = new ComplexObject();
        cookTheBooks(bar);
        do some other things...
        return;
    }

    private void cookTheBooks(ComplexObject bar)
    {
        foo++;
        bar.Total=bar.Total*cookFactor;
        return;
    }
}

Here foo is a member variable. It’s created when the class is created, not when each instance of kung is called. If two threads happen to call kung at the same time, both will try to access the same instance of foo. This could have disastrous results.
This is just one of the reasons why managing scope is important.

Next time I promise I’ll get on to locking.

The Threading Series

Article 1: Threading: Get Up To Speed Now!

Article 2: Thread Safety: Why Local Variables Are Good

Article 3: Threading: Locking and Deadlocks Introduced

Article 4: Combating Simple Deadlocks and Semaphores

Article 5: Semaphores and Message Passing

Threading: Get Up To Speed Now!

Reading Time: 5 minutes

Let’s talk about multi-threading and concurrency. Why? Because we need to. Developers have been trying their best to avoid it for years because a lot of people have a really hard time with it. The problem is that it’s about to become really important. The chip manufacturers have hit a hard limit on the speed of processors, the can’t make them go any faster. What they can do is add more cores: 2 core and 4 core are common at the moment, but 8 is on its way to the desktop soon and this number is just going to go up and up.

The upshot is that if you’re still programming in a sequential, single threaded model your products going to be killed in the marketplace by competitors who actually know what they’re doing.

Why am I being so vocal about this? Well concurrency is not something you can busk, if you don’t fully understand the problems you’ll land yourself in a world of pain. I know, I’ve spent weeks tracking down multi-threading bugs introduced by developers who thought they knew what they were doing (including me). It’s a hell of a lot better if you don’t introduce the problems in the first place.


First let’s first clear up a few simple misunderstandings. A thread is a sequence of actions that can run in parallel to another sequence of actions. A thread is usually made from a method or function call. It doesn’t have any relationship with objects other than the fact that some environments provide handy thread management objects. A thread can use one object, multiple objects or none at all. An object can be accessed by many threads. There’s no magic thread safety between objects, contrary to what some people seem to think. Unless you’ve implemented some thread safety measures acting on one object from another is not “thread safe”.

In C# you can use threads directly, but more often you would use the Task Library or the Parallel library. Microsoft are clear that both these libraries use threads, so if you’re using these libraries you need to understand threading and concurrency. They’re no get out of jail free card in that respect.

So here’s a trivial example of why threads are useful. A simple GUI application has only one thread. The user clicks something and whilst the action behind that is being performed the user has to wait, the GUI won’t even be updated so if it’s a long task the application will be unresponsive until the action completes. Instead we could start a second thread to perform the action in parallel to operating the GUI. The application now won’t freeze whilst we’re performing the action, and when it completes we can tell the user.

Here’s a simple diagram of that and you can download an example in this zip file (c# / VS2008).

Why Single Threaded GUIs are So Limited

So where’s the danger? Well, the basic problem is mind-numbingly dull. The next diagram shows an example that I see annoyingly often with object initialisation.

Poor programming causes many problems...

Time runs from top to bottom with two threads are running simultaneously. Both of them are trying to deal with one email object, but the timing between the threads screws things up for us and we end up declaring our undying love for Dave, twice. To add insult to injury, we also end up creating a spurious email object. Whilst in a managed language the garbage collector will pick this up for us (which is bad, but not criminal), in an unmanaged environment we’ve just introduced a memory leak and that’s a defenestration offence. This is not a good day at the office.
As an aside, don’t be fooled into thinking that this can’t happen if you’re only running on one core. The way threads are (usually) scheduled on a single core means that this kind of thing is entirely possible.

The key is that anywhere where changes are made to something that is accessed by more than one thread there can be a problem, it’s not just where multiple threads are making changes either. Consider a personal finance object. One thread asks it to move £20 from the current account to savings. It duly takes the money off the current account but before it adds it to the savings account another thread reads the balance of the current account and savings account and adds them together to get the total available funds, which at that precise moment is wrong.  The personal finance object then adds the £20 to the savings account and you have no idea where the incorrect total came from or even that you have one. The examples zip file (c# / VS2008) contains a ludicrously simple program to demonstrate the problem.

One fallacy that I’ve heard from even quite senior and experienced developers is “ah, but what are the chances of that actually happening?” In the personal finance case, on a single core, actually it’s not a lot and this is why people have got away with writing appalling multi-threaded code for so long. But with a more complex operation or one on multi-core processors the chances of this kind of assumption screwing you over are significant.

So what weapons do we have in our arsenal to fight this kind of cock-up? There are three fundamentals, managing scope, managing locking and message passing. Scope is the easiest to cover so I’ll do so now, locking and message passing will have to wait for until the next article.

So, scope: remember way back in programming 101 that you were told to manage scope? A lot of threading problems happen because things are shared between threads when they shouldn’t be and it really is that simple. Local variables are your friends because they are created when the method is called and go out of (at the very least) scope at the end of the method. If two instances of the method are called on the same object at exactly the same time, there will be two totally separate instances of the local variables. If something isn’t shared with any other thread, it is by definition thread safe. Use local variables instead of private member variables where it’s practical to do so.

There are caveats, such as singletons and other objects that share resources, but any basic variable or object is thread safe if it’s only a local variable. For pedants, I must now mention the speed implications and that passing them by reference somewhere can make them unsafe, I’ll cover more of those in the next article.

The next most safe is private member variables. Our object has control over the way these are accessed so we can ensure that they’re used in a thread safe manner. A list can make sure in its add, delete and access methods that it carries out the correct locking on its internals so as to make sure that nothing that is not thread-safe happens.

There’s not a lot we can do about publicly accessible entities though. At least if they’re properties we can control the way they’re got and set, but we can’t guarantee our own consistency. The email example shows this, where the email’s properties are being set externally and it’s the external logic, not the logic in the object that isn’t thread safe. We can combat this by introducing internal controls on the way properties can be set, for instance we could have made To and Subj read only and introduced a SetHeaders method that took both at once and was thread safe, but overuse of this technique can make code less clear and hamper productivity. It’s also somewhat treating the symptom, rather than the cause. There’s no substitute for getting it right in the first place.

Next time I’ll explain more about exactly why local variables are (generally) thread safe and look at message passing. Don’t worry, I’ll start looking at locking in post 3.

The Threading Series

Article 1: Threading: Get Up To Speed Now!

Article 2: Thread Safety: Why Local Variables Are Good

Article 3: Threading: Locking and Deadlocks Introduced

Article 4: Combating Simple Deadlocks and Semaphores

Article 5: Semaphores and Message Passing