LA.NET [EN]

MultithreadingArchive

Jun 08

Multithreading: the IAsyncResult interface

Posted in C#, Multithreading       Comments Off on Multithreading: the IAsyncResult interface

In the last post, we’ve started looking at the APM model used by the .NET framework. Today we’re going to talk about the role played by the IAsyncResult interface. Currently, the IAsyncResult interface has the following members:

public interface IAsyncResult {
    object AsyncState { get; }
    WaitHandle AsyncWaitHandle { get; }
    bool CompletedSynchronously { get; }
    bool IsCompleted { get; }
}

The AsyncState property lets you access the state parameter passed to the BeginXXX method. The AsyncWaitHandle property is a WaitHandle which you can use to wait on (it’s only one of the options you have for waiting). Most implementations tend to use a ManualResetEvent object which gets signaled when the operation completes.

The CompletedSynchronously property lets you know if the operation completed in synchronous or asynchronous fashion. You might be curious on why you need this property. After all, won’t the APM always complete asynchronously? The answer to this is a little more complicated than it may appear at first sight…Most of the time, operations will complete asynchronously and this property will return false. In fact, most frameworks that implement the APM rely in the thread pool and will always return false.

However, the APM model is also used by I/O and, in those cases, there’s the chance of the I/O operation completes in a synchronous fashion. When this happens, it means that the thread that called the BeginXXX method, will also handle the EndXXX method. if you were to start another asynchronous I/O call from within the callback, you could end up using all the stack and getting a stack overflow exception.

Finally,there’s the IsCompleted property,which ends up returning true when the work is done.

As you can see, there’s not much into consuming an IAsyncResult interface. The problematic part is implementing it. We’ll return to that in the future, but before doing that, let’s see what options we have for waiting for the completion of an asynchronous operation when we use this mode.

Keep tuned for more on multithreading.

Jun 07

Multithreading: introducing the asynchronous programming model

Posted in C#, Multithreading       Comments Off on Multithreading: introducing the asynchronous programming model

Today we’re going to keep looking at multithreading on the .NET framework and we’re going to start talking about the oldest async model you’ll find in the .NET framework: the APM (asynchronous programming model). You might be asking why you need an asynchronous programming model and why shouldn’t you use the threads or thread pool directly.

The APM is one of two parallel modes (we’ll leave the event based pattern for future posts) we’re going to look at and it can be seen as a pattern for letting operations execute in parallel and take care of all the internal details that go with these kind of operations (waiting, polling, etc). We all know the value of patterns, so I guess that’s enough for justifying its use. As I’ve said, the APM is the oldest async model and has been around since the release of .NET.

It relies on the use of the IAsyncResult interface and on the usage of a couple of begin and end methods on the form BeginActionName and EndActionName. The APM is the way to go when you’re building reusable libraries (you’ll typically use the event based pattern for UI components).

In theory, you can transform any synchronous operation in an asynchronous operation by adding a couple of methods. For instance, if you’ve got a synchronous method named Calculate and you want to change your API so that it supports asynchronous processing through the use of the APM pattern, then you need to start by adding two methods named BeginCalculate and EndCalculate.

The BeginCalculate method accepts the same number of parameters as the Calculate method + two new parameters:

  • an AsyncCallback method, which will be invoked when the operation completes;
  • an object state parameter, which allows you to pass state to the callback method.

This method always returns an instance of type IAsyncResult interface. The AsyncCallback delegate looks like this:

public delegate void AsyncCallback(IAsyncResult ar);

The EndCalculate method receives a single parameter, of type IAsyncResult. As we’ll see, there are several options for waiting for the async operation to complete. What you should keep in mind is that you should always call the EndCalculate method when to recover the result of the operation or to catch eventual exceptions that might have been through during the asynchronous operation.

If you don’t call the method,you’re probably swallowing exceptions and,even worst, you’re not cleaning up the internal structures used. Btw, and just to wrap up with the EndXXX method, it’s important to mention that it returns the same type as the synchronous method.

As I’ve said, most of the work necessary for making everything work, is encapsulated by the IAsyncResult implementation which is built during the BeginCalculare method. Since this is a really important interface, we’ll have to dedicate a complete post to it and that’s what we’ll do  on the next post.

Keep tuned for more about multithreading.

Jun 05

Now that we’ve ended our study of the thread pool, you know that we’ve got two ways of spanning new threads for performing work in parallel: we can manage the thread lifetime by using the Thread class directly or we can rely on thread pool for managing threads for us. Since there are options, you might be wondering which option you should choose for your code.

Once more, there’s really no definitive answer: it all depends on your scenario. If I had to give an answer to that, I’d say that most of the time you’d be better using the thread pool instead of creating your own threads. There are, however, a couple of scenarios where you should create your threads explicitly. For instance:

  • if you need to set the apartment type;
  • if you need to set the type of thread (pool threads are always background threads);
  • if the application will take a long time to end.

Btw, there are also some scenarios where you should be careful in relying on the thread pool. For instance, in ASP.NET apps, you shouldn’t forget that ASP.NET will also use it for its own work (everything should go well if you’re just queuing small tasks: just don’t get too greedy and start queuing work on the thread pool:),,)

For those that are worried with performance, I guess that using the pool will improve it for many scenarios (specially if we’re talking about parallelizing small tasks) because you’re amortizing the thread creation by using the same threads several times for different tasks.

The new .NET 4.0 thread pool introduces several new features which you can reuse when using the parallel library. This is really cool stuff and I’ll redirect you to Daniel Moth’s excellent blog for getting more details on this new feature.

And that’s it for now. In the next posts, we’ll keep looking at multithreaded

Jun 04

Multithreading: I/O and the thread pool

Posted in C#, Multithreading       Comments Off on Multithreading: I/O and the thread pool

When we started looking at how we could use the thread pool for asynchronous work, I (only!) mentioned three options:

  • use the pool to run a task when IO completes;
  • run a (possible recurrent) task at a specific time;
  • execute a task when a kernel object is signaled.

There is still another option: you can also rely on the thread pool’s I/O completion support and write code that runs a callback – aka completion callback – on a thread from the pool in response to the end of an asynchronous I/O operation.

The CLR pool maintains a single I/O completion port per process. I/O completion ports were introduced in windows to improve scalability. The docs say that “I/O completion ports provide an efficient threading model for processing multiple asynchronous I/O requests on a multiprocessor system”. Even though I/O ports are a powerful concept, in managed code you’ll probably use them for supporting asynchronous I/O.

Let’s concentrate on files (I believe this is the most common case)…The idea is the following: you start by opening a file for an asynchronous operation and bind the handle of that file to the process wide completion port (notice that you can bind several handles to the same completion port). After doing that, you can simply start the required asynchronous operation and keep doing other interesting things (since you’ve started an asynchronous operation, the thread from where you started the async read or write won’t block).

Whenever that operation completes, it will queue a packet on that I/O completion port. The port will then proceed and use one of the thread pool’s thread to run the callback you’ve specified. The greatest advantage of using the thread pool for doing this kind of thing is that it already manages its own completion port and you don’t have to worry about the creating the “correct” number of threads that should be waiting on the port for the completion packets (ie, you’re free of having to manage the port itself and the threads that wait on it – not sure on what you think, but it does sound good to me 🙂 ,,).

Even though you can write the “low-level” code for doing this kind of stuff on managed code (notice the irony of calling this interaction “low-level” code), the truth is that in most scenarios you’ll end up using the asynchronous IO APIs introduced on the .NET framework since they’re integrated with the pool.

Anyway, it would be probably a good idea to take a look at same code before using the high level version calls. Fortunately for me, someone else has already posted some demo code online and this means that I will simply redirect you to that interesting post.

And I guess it’s all for now. Keep tuned for more on multithreaded applications.

Jun 03

Multithreading: coding the register wait pattern

Posted in C#, Multithreading       Comments Off on Multithreading: coding the register wait pattern

Yesterday we’ve looked at the theory behind registered waits (btw, there were some errors on that post, but I think I’ve corrected them now). Today, we’re going to look at some code. Let’s see what happens when we use a ManualResetEvent for waiting on:

class DumbHandle : WaitHandle { }
static void Main(string[] args) {
    var evt = new ManualResetEvent(false);
    var counter = 0;
    var registerWait = ThreadPool.RegisterWaitForSingleObject(evt,
        (state, timedout) => {
            Interlocked.Increment(ref counter); //get number of queued calls
            Console.WriteLine("registered wait fired");
        },
        null,
        Timeout.Infinite,
        false);
    evt.Set();
    Thread.Sleep(10);
    evt.Reset();
    var handle = new DumbHandle();
    registerWait.Unregister(handle);
    Console.WriteLine("total count: {0}", counter);
}

If you run the previous code, you’ll see that the sleep interval will be more than enough for firing the callback several times…notice that we’re passing a handle  to the Unregister method so that all the callbacks have a chance of running before the program ends. If you don’t wish to do that, just pass null instead of a valid handle.

Since this is a really simple  example,we’re not checking the values of the parameters passed to the callback method (in fact,in this example state will always be null and timeout will always be false because we’re specifying Timeout.Infinite for the timeout parameter on the RegisterWaitForSingleObject call).

You might be tempted to write code like this:

evt.Reset();
registerWait.Unregister(evt);
Console.WriteLine("total count: {0}", counter);

Please don’t! Doing this will result in getting more callbacks queued on the thread pool (which might run or not) and that’s not what you want!

I guess there isn’t much more to say about registered waits…keep tuned for more on multithreaded apps.

Jun 02

Multithreading: registered waits

Posted in C#, Multithreading       Comments Off on Multithreading: registered waits

In this post, we’re going to keep looking on how we can reuse the thread pool’s threads for executing specific tasks. This post is all about registered waits. A registered wait allows us to specify a callback that will be invoked when a predefined kernel object is signaled. In .NET, we register a wait callback through one of the several static overloads of the RegisterWaitForSingleObject method. Here’s one of those overloads:

public static RegisteredWaitHandle RegisterWaitForSingleObject(
                 WaitHandle waitObject,
                 WaitOrTimerCallback callBack, 
                 object state,
                 int millisecondsTimeOutInterval,
                 bool executeOnlyOnce)

The first paramater (waitObject) lets you pass a reference to one of the existing kernel object (ie, one of the several derived WaitHandle classes). The second parameter is a delegate of type WaitOrTimerCallback:

public delegate void WaitOrTimerCallback(object state, bool timedOut);

As you can see, any compatible method receives a reference to the state parameter that you’ve passed to the RegisterWaitForSingleObject. The timeOut parameter that is passed to the callback method lets you know if the the callback is being executed because the wait timed out (which happens whenever the millisecontsTimeOutInterval you specified on the RegisterWaitForSingleObject ends). Finally, if you’re registering a wait on a object that stays signaled, you’ll be passing true to the executeOnlyOnce parameter (or you’ll get a never ending callback execution!).

Besides the RegisterWaitForSingleObject,there’s also an UnsafeRegisterWaitForSingleObject. The difference is that the unsafe method won’t propagate the context to the thread that handles the callback. Whatever method you use,both end up getting an instance of the RegisterWaitHandle type.

You’ll end up using that return instance for cancelling a wait, which you do by calling the Unregister method. Even if you pass true to executeOnlyOnce, you should also call the Unregister method when you’re done (the docs say that it helps improve the performance of the GC).

After the Unregister method has been called, it’s guaranteed that no more callbacks will be queued. It’s also important to keep in mind that, if there were any calls already queued, then those methods will still be invoked.

When you’re done with the RegisterWaitHandle, you should release it by calling Dispose Unregister. If you want to be notified when all callbacks have finished, then you should pass a valid WaitHandle (it’s really similar to what we’ve seen in the previous Timer post). Don’t pass the same object you’ve used for the registered wait or you’ll get into trouble!

Internally, the thread pool will use the same thread for waiting on groups of 63 different kernel objects. When that number is reached, a new thread will be used for waiting on the next 63 objects. Internally, the “waiting” thread uses a “group” of 64 kernel objects (the 64th slot is used for an interval event object) on which it uses a wait any approach.

Unlike unmanaged code, where you can use the “waiting” thread for executing the registered callback (this behavior is specified through a flag, btw), in managed code all callbacks will always be dispatched on a separate worker thread. Btw, it’s a really bad idea to use  a Mutex for a registered wait because you cannot get the wait registration to run on the same thread that owns the Mutex.

And I guess that’s all I have time for today. On the next post, we’ll take a look at some code. Keep tuned…

Jun 01

As we’ve seen, we can also use the thread pool for executing a (possible recurring) task at a specific time. To do that, we need to take a look at the Timer class. Initializing a timer is done through one of its constructors:

public Timer(TimerCallback callback);
public Timer(TimerCallback callback, object state, int dueTime, int period);
public Timer(
    TimerCallback callback, object state, long dueTime, long period);
public Timer(
   TimerCallback callback, object state,
   TimeSpan dueTime, TimeSpan period);
public Timer(
   TimerCallback callback,object state,uint dueTime, uint period);

As you can see, all accept a delegate of type TimerCallback delegate which will be invoked (possibly, several times) by one of thread pool’s thread:

public delegate void TimerCallback(object state);

The delegate receives the object you pass through the state parameter of the constructor (ie, when you use a constructor that uses that parameter; in the other cases, you’ll get null).

The dueTime parameter lets you specify the first time the timer will invoke the callback delegate. The int and double overloads let you specify that info in milliseconds. The other overload lets you use  TimeSpan for specifying that interval. For creating a timer that fires immediately, you should pass 0. Notice also that you can pass –1 for this parameter (that’s what the constructor that receives only the delegate parameter does). Doing it results in creating a disabled timer (which can be latter enabled through the call of the Change method).

The period parameter (which, again, can be defined in milliseconds – int or long overloads – or through a specific TimeSpan) is there for setting the interval between invocations of the specified callback. If you don’t want to have recursive fires, then you should pass the Timeout.Infinite (-1) to that parameter.

Here’s the most basic snippet of code that shows its usage:

var timer = new Timer(
                obj => Console.WriteLine(DateTime.Now),
                null, //no state
                0, //start right away,
                1000 //repeat each second
                );
Thread.Sleep(4000); //sleep main thread

The previous example instantiated a new timer which prints the current date and time. It fired right away (notice the 0 to the dueTime parameter) and repeated the callback invocation every second (until the program ended). If we wanted to be perfectionists, then we should wrap the timer in using block (or, alternatively, use a try/finally block) so that it gets disposed when we’re done with it.

It’s important to know that there are 2 overloads of the Dispose method. The simple no parameter version stops the timer from firing in the future and releases it. However, there’s still the problem of having tasks that are executing or waiting to be executed in the thread pool (queue). If you’re worried with that and would prefer them to be run before exiting, then you can use the other overload which receives a WaitHandle reference that will be signaled when all the waiting tasks have been executed. Take a look at the following code:

var evt = new ManualResetEvent(false);
var timer = new Timer(
     obj => { Thread.Sleep(1000); Console.WriteLine(DateTime.Now); },
     null, //no state
     0, //start right away,
     1000 //repeat each second
     );
timer.Dispose(evt);
evt.WaitOne();

If you run it, you’ll see that the event will get signaled when the 1st timer’s callback execution ends. Without the event, you wouldn’t see anything printed because the program would terminate immediately (remember that timers use thread pool’s thread and that these are background threads). Btw, there’s an interesting trick I’ve picked up from Joe Duffy’s book (which is *really really* recommended reading): create a dumb WaitHandle instead of using one of the existing ones that rely on kernel objects:

class DumbHandle: WaitHandle{}
var evt = new DumbHandle();
//some code as before

After instantiating a timer, you can enable or disable it through the Change method. Btw, you can also use this method to change the firing intervals at which the callback delegate will be executed. Here’s some code that disables a timer and then enables it:

var timer = new Timer(
                obj => { Console.WriteLine(DateTime.Now); },
                null, //no state
                0, //start right away,
                1000 //repeat each second
                );
timer.Change(-1, -1); //disable timer
Thread.Sleep(3000);
timer.Change(0, -1); //enable and fire right away

Before ending, there’s still time for pointing on interesting gotcha: you shouldn’t take more time in the callback delegate than the repetition interval you’ve set up. Doing that might lead to creating lots and lots of “unneeded” threads which will end up causing the degradation of your app. Just try the following code:

var worker = 0;
var io = 0;           
Console.WriteLine( "worker: {0}, io: {1}", worker, io );
var timer = new Timer(
      obj => {
                  Console.WriteLine(Thread.CurrentThread.ManagedThreadId); 
                  Thread.Sleep(30000); },
     null, //no state
     0, //start right away,
     1 //repeat each second
     );          
Thread.Sleep(40000);
ThreadPool.GetAvailableThreads(out worker, out io);
Console.WriteLine("worker: {0}, io: {1}", worker, io);

Ok, that should be enough for making a point, right? (in my machine, I’ve started with 0 worker threads and ended with more than 400 threads). btw, the same goes for locking thread pools used by  timers (ie, make sure they don’t block longer than the firing interval you’ve specified).

And that’s all for today. Keep tuned for more on multithreaded apps…

Jun 01

In the last post, we’ve seen how we could use the thread pool for queuing work items that will be executed in one of the existing threads maintained on the default thread pool. As we’ve seen, there’s no way to say “wait for the executing actions” without using one of the synchronization kernel objects we’ve met in previous posts.

In that last post, I’ve queued one work item and used a ManualResetEvent for waiting until the work is completed. A friend of mine asked me what’s the best option for waiting on several work items. Should we use several kernel objects? Here’s the code we generally see in these cases:

var evts = Enumerable.Range(0, 3)
        .Select(i => new ManualResetEvent(false))
        .ToArray();
var wrkThreads = Enumerable.Range(0, 3)
        .Select(i => new Thread(() => { Console.WriteLine("Thread {0}", i); Thread.Sleep(2000); evts[i].Set(); }));
Console.WriteLine( "Starting secondaryThreads");
foreach(var t in wrkThreads){
   t.Start();
}
WaitHandle.WaitAll(evts);

Yes, this works and you’ll see it across several MSDN samples…no doubt about it. But is this really the best option? It might be, but can we get away without using all those event objects? Yes, we can :,,) How? let’s think about it…and what if instead of creating several events, we had only one and used a counter for signaling it when everything is done? Here’s how it would look like:

var evt = new ManualResetEvent(false);
var cbCounter = 3;
var wrkThreads = Enumerable.Range(0, cbCounter)
      .Select(i => new Thread(() => {
                                Console.WriteLine("Thread {0}", i);
                                Thread.Sleep(2000);
                                if( Interlocked.Decrement(ref cbCounter) == 0 ){
                                    evt.Set();
                                }
      }));
Console.WriteLine( "Starting secondaryThreads");
foreach(var t in wrkThreads){
  t.Start();
}
evt.WaitOne();

Notice that we’re using the Interlocked.Decrement method for decrementing the counter in an atomic and thread safe way. I’ve also seen this code written by using locks, but I think that the Decrement method invocation is the preferred option for most (if not all) cases.

And that‘s it. Keep tuned for more.

May 28

As we’ve seen in the last post of the series, we can use the thread pool for scheduling several “types” of asynchronous operations and to amortize the penalty we pay when we need to create extra threads. In fact, I’d say that most operations should be performed by using a thread from the thread pool.

Today we’re going to look at one of the operations we can perform on thread pool: queuing work items. Interacting with the CLR managed thread pool can be accomplished through one of the several static methods of the ThreadPool class. For queing work items, we can use one of two methods: QueueUserWorkItem or UnsafeQueueUserWorkItem.

public static bool QueueUserWorkItem(WaitCallback callBack);
public static bool QueueUserWorkItem(WaitCallback callBack,
                                                                             object state);
public static bool UnsafeQueueUserWorkItem(WaitCallback callBack,
                                                                                 object state);

According to Joe Duffy’s excellent book, you should disregard the return value because failures will always be communicated through exceptions (I did check the docs and they don’t mention what false means :),,)

The main difference between the two is that the latest does not capture the ExecutionContext when you queue the work item (which means that it won’t also be used when the callback you pass is invoked). Both methods allow you to pass a reference to some object which will get passed to the callback when its processed.

Even though QueueUserWorkItem is more “secure” than the UnsafeQueueWorkItem (due to the fact that the context is captured and flowed – since the SecurityContext is part of the ExecutionContext, this means that you cannot elevate privileges by queuing work items on the thread pool), it’s also true that QueueUserWorkItem is slower than UnsafeQueueWorkItem (due to the overhead imposed by capturing and restoring the context).

When using a thread from the pool, it’s important to understand a few points:

  • you don’t control the thread that will invoke your callback;
  • the pool has only background threads. This means that they won’t keep a process running when the main thread exits. If you need to ensure that, then you need to create a thread by hand (ie, you need to use the Thread class);
  • Don’t forget the clean up before ending your work (especially if you’ve set cultures and other stuff). Even though these might get cleaned, there are some that won’t (ex.: TLS state – which, btw, you shouldn’t be using).

Enough talk…let’s see some code:

static void Main(string[] args) {
Console.WriteLine("Main thread Id: {0}",
             Thread.CurrentThread.ManagedThreadId);
  var evt = new ManualResetEvent(false);
  ThreadPool.QueueUserWorkItem( state => {
       Console.WriteLine("Thread Id: {0}",
                      Thread.CurrentThread.ManagedThreadId);
       Thread.Sleep(2000);
       Console.WriteLine("FInishing work");
       evt.Set();
     });
     evt.WaitOne();
     Console.WriteLine("Ending program");
}

The QueueUserWorkItem method expects a WaitCallback delegate which looks like this:

public delegate void WaitCallback(object state);

The state parameters will only contain a valid value when you use the overload which receives an object parameter. As you can see, the code is pretty similar to the one you had when we created threads “by hand”.

The most important detail of the previous code is synchronization! If we didn’t wait on the event, we wouldn’t really see much because the process would terminate before the secondary thread would have a chance to end (since pool’s threads are background threads, they don’t keep the process alive when all foreground threads have ended running).

And that’s it for today. Keep tuned for more on the thread pool.

May 27

Until now, we’ve been starting threads by creating instances of the System.Threading.Thread class in the samples. Thread creation isn’t cheap! If we’re creating a thread just to run a small task, then the thread’s creation might completely outweigh the advantage of running such a small task.

In most cases, instead of creating new threads, we should simply run those tasks on one of the threads maintained on the thread pool that is automatically created for all managed processes. Even though the most used operation is queuing a task in the thread pool, you can also:

  • use the pool to run a task when IO completes;
  • run a (possible recurrent) task at a specific time;
  • execute a task when a kernel object is signaled.

The global CLR thread pool maintains two “sub-pools”. One is used for IO and the other is used for the remaining possible options mentioned above. By default, there is one pool per process and the IO “sub-pool” will contain a maximum of 1000 threads, while the other “sub-pool” (aka worker pool) contains a maximum of 250 threads.

wow! wtf? so many threads? Yes, that’s the maximum number you’ll get per process.However, when the process starts, there aren’t really any threads on the pool ,,)ie, both “sub-pools” are empty. Threads are created as needed (ie, while new task are queued on the thread pool) until the specified minimum number of threads is reached.

Notice that threads might not be immediately created for work items that are queued on the thread pool. When the minimum number of threads is reached, the thread pool will throttle the creation of other threads (meaning, it won’t immediately create new threads per task that is queued on the thread pool). In these cases, the thread pool will create a new thread as needed from 30 to 30 seconds if all the predefined minimum number of threads are all busy doing work.

When a thread ends its work, it returns to thread pool where it waits for more work. If the current number of waiting threads is greater than the minimum specified, then those additional threads will be terminated.

And that’s it for this post. We’ll be returning to this topic in the next posts.

May 27

Protected: Using condition variables

Posted in C#, Multithreading       Comments Off on Protected: Using condition variables

This content is password protected. To view it please enter your password below:

May 27

Multithreading: condition variables

Posted in C#, Multithreading       Comments Off on Multithreading: condition variables

There are times when a thread needs to wait  for a specific condition to be true. Since this condition tends to involve shared state, then you know that you must use some sort of synchronization to ensure proper update of the data used by the condition. When we looked at kernel objects, we’ve seen that there was a method (SignalAndWait) that you can use to signal a kernel object and wait on another atomically. This is good and helps with those nasty race conditions that might occur if you have to signal one object and wait on another.

Now, when you use the sync primitives (CLR locks and reader/writer locks), we stop having access to the kernel objects used by those high level primitives! This means that we’re back to the race condition when we need to, for instance, exit a critical section and set an event. And this is the problem that condition variables solve.

In .NET, condition variables have first class support, through the Monitor’s Wait and Pulse methods. Calling the static Wait method results in releasing the lock on an object and blocking the current thread until it reacquires that lock (in practice, this means that the thread that called Wait goes into the waiting queue of that object). When the method returns, it will have reacquired the lock (something that is only possible when another thread calls the Pulse or PulseAll method).

It’s important to understand that you can only call Wait over an object for which the calling thread owns the lock (failing to respect this results in a SynchronizationLockException being thrown). The same is true for the Pulse and PulseAll methods. In practice, this means that Wait,Pulse and PulseAll methods must be invoked from within  a lock block!

Notice that since the Wait method needs to reacquire the lock,it will block until it achieves that purpose (even if you use one of overloads that expect a timeout). This means that you’ll have to use the return values to check if the wait ended before the specified timeout (in which case, true is returned).

As we’ve said, you need to signal a condition by calling the Pulse/PulseAll methods. This is the only way to unblock a thread that has gone into the waiting queue of an object. On the next post, we’ll see a practical example of how to use this feature. Keep tuned!

May 26

In the previous posts, we’ve seen how we can use monitors and any CLR object for getting a critical region. Whenever you need to get a critical region, using a CLR lock for ensuring proper access. However, there will be times when, for instance, you’ll have much more reads than writes. In these cases, using a lock is still correct, but it is not the best way to get good performance.

This is where the reader/writer locks enter. When using these type of locks, a thread will have to specify the type of access it desires (read or write). At any time, there can only be a write lock. However, there can be several read locks (as long as there are no write locks).

In practice, this means that we can have several threads in the region if those threads are only interested in “reading”. Whenever a thread says that it’s interested in writing,it needs to acquire the write lock (or upgrade the read lock,if it has one). When the write lock is acquired, all the other readers (and writers) need to wait until that thread leaves the critical region and releases the lock.

In .NET, there are two types of reader/writer locks: the old ReaderWriterLock and the new (as of .NET 3.5) ReaderWriterLockSlim. I’ll only be looking at the ReaderWriterLockSlim class because I’m currently working over 3.5 only.

When we instantiate a RederWriterLockSlim, we can decide if recursion will be allowed. By default, it won’t, so if you need it, you’ll have to use the constructor which expects a value from the LockRecursionPolicy enumeration. After getting a valid reference to a lock of this type, we can use one of several methods for acquiring a read or write lock. In fact, the lock supports a third type of lock: an upgrade lock. The first two are the ones most people are used to; the last can be used when a thread isn’t sure if it will need read or write access.

This last scenario involves calling the EnterUpgradeableReadLock. After getting the updatable lock, the thread must decide (in the least amount of time!) if it needs read or write access. If it needs read access, it should call the EnterReadLock method; on the other hand, if it needs write access, it should simply call the EnterWriteLock method. When you decide to go with the read lock, you should also call the ExitUpgradeableReadLock method (right after the EnterReadLock method call) so that other previously read and upgrade locks calls that were waiting can proceed.

Ok, now we’re ready to see some code:

class MyCache: IDisposable {
    private IDictionary<String, Object> _cache = 
                                                                  new Dictionary<String, Object>();
    private ReaderWriterLockSlim _locker = new ReaderWriterLockSlim();
    public Object this[String key]{
        get {
            _locker.EnterReadLock();
            try {
                return _cache[key];
            } finally {
                _locker.ExitReadLock();
            }
        }
        set {
            _locker.EnterWriteLock();
            try {
                _cache[key] = value;
            } finally {
                _locker.ExitWriteLock();
            }
        }
    }
    public void Dispose() {
        Dispose(true);
    }
    ~MyCache() {
        Dispose(false);
    }
    private void Dispose(Boolean disposing) {
        if (!disposing) {
            return;
        }
        _locker.Dispose();
    }
}

This is really simple class which uses a reader lock for getting a value from the list and a writer lock for writing an entry to this custom cache (notice that we’re not using upgradeable locks in this simple example). As you can see, we’re implementing IDisposable to ensure that we release the reader/writer lock when we’re done. Here’s some code that tests the previous “cache” and that starts several writers and readers:

static IEnumerable<Thread> CreateWriterThreads(String[] keys, MyCache cache){
    var aux = Enumerable.Range(1, keys.Length)
                        .Select( i => new Thread( () => {
                            var key = "item" + i.ToString();                                    
                            cache[key] = DateTime.Now; }) ) ;
    return aux;
}
static IEnumerable<Thread> CreateReaderThreads( Int32 numberReaders, String[] keys, MyCache cache){
    var aux = Enumerable.Range(1, numberReaders)
        .Select(i => new Thread(() => {
            Console.WriteLine("Thread {0} starting", i);
            Thread.Sleep(100);
            foreach (var key in keys) {
                try {
                    Console.WriteLine("item {0} in thread {1} with value {2}",
                                                                 
                       key, i, cache[key]);
                } catch {
                    Console.WriteLine("item {0} in thread {1} not in cache yet", key, i);
                }
            }
            Console.WriteLine("Thread {0} ending", i);
        }));
        return aux;
}
static void Main(string[] args) {
    using (var cache = new MyCache()) {
        var keys = new[] { "item1", "item2", "item3" };
        var writerThreads = CreateWriterThreads(keys, cache);
        var readerThreads = CreateReaderThreads(10, keys, cache);
        foreach (var writer in writerThreads) {
            writer.Start();
        }
        foreach (var reader in readerThreads) {
            reader.Start();
        }

        Thread.Sleep(10000); //wait enough time for everything to complete
    }
}

And that’s all for today. Keep tuned for more on multithreading.

May 25

Multithreading: more on CLR locks

Posted in C#, Multithreading       Comments Off on Multithreading: more on CLR locks

In the previous post we’ve taken a quick peek at how we can use the CLR lock primitive. In this post we’re going to talk about some interesting things you might need to know when you work with these locks. According to Joe’s reference, the CLR locks use some spinning internally before waiting on a kernel object. Unfortunately, there’s really no way for you to change the time it spins (if you’re a C/C++ programmer, you probably know that you can control the amount of spinning time before waiting).

One thing that we didn’t discuss is what to expect when we have exceptions. For instance, consider the traditional code we’ve seen before:

Monitor.Enter(locker);
try { 
    Thread.Sleep(1000);
}
finally {                 
    Monitor.Exit(locker);
}

Ok, now, what happens if you get an exception between Monitor.Enter and the try block? Impossible, you say…I thought that too, but it seems like the JIT compiler could put (it seems like the x64 does that on pre 3.5 versions!) a simple nop instruction between the Monitor.Enter and the try block (if we get an async exception when the pointer was at that NOP instruction, then we wouldn’t be able to release the lock because the try block wouldn’t run).

Fortunately, it seems like the C# lock keyword ensures that there are no IL instructions between Monitor.Enter and the try block (at least, in non-debug builds for the X64; it seems like this problem does not affect the x86 JIT compiler). Since the Enter method is entirely written in *unmanaged* code,then it can’t also be interrupted by a managed exception (meaning that even if you get a managed async exception during that method,you’ll only get it inside the try block).

So, I guess that it’s fair to say that you should be fairly safe if you’re not using a debug release in x64.

As we’ve seen, all managed objects can be used for “locking on”. Understanding why and how this works is a good exercise (and that’s what I’ll try to do here based on what I’ve learned from Richter’s and Duffy’s books – it goes without saying that both are required reading for anyone working in .NET). All CLR objects have an object header (a chunk of memory) which resides before the address in memory to which a reference points to. The CLR uses this header for storing the hashcode (after you’ve called GetHashCode, that is), COM interop info and for the so called thin lock.

The thin lock is of special interest for us: it contains the ID of the monitor’s owning thread encoded in less than a natural word. When possible, the CLR will always use this thin lock in the header for locking. Unfortunately, things start to get a little “tight” when you need to put all these things in the header. For instance, if we need to allocate an event handle for waiting purposes (which is done by the monitor, as we’ll see in the next paragraphs), more space will be needed. When this happens, the CLR does its magic and performs the so called header inflation.

Whenever the CLR starts, it creates an array of sync blocks. By default, the header object doesn’t point to none of these blocks. When the CLR sees that the object needs more space for its header, it will simply check for an available sync block from that array and it will set the header to the index of the sync block that should be used. As you might expect, the contents that were stored on the header are copied to the sync block.

Btw, and since we mentioned sync blocks, you should also keep in mind that the CLR is able to increase the number of blocks in the array and it will also manage the deflation of the header (done during garbage collection), all in thread safe manner.Back to the topic, which is how monitors implement locks…

As we’ve seen, locks always incur in spinning before waiting on a kernel object. Whenever the spinning isn’t enough for allowing a monitor to acquire the critical section, an auto-reset event will be created and a reference to it will be put in the associated sync block (as we’ve seen, inflation is always needed when we need to wait on a kernel object). Deflation is always performed during GC time for all the objects whose sync block aren’t needed any more (don’t forget that the sync block holds other info besides “locking” and they won’t be “deleted” if that info is still needed). Regarding our topic of threading, it’s important to understand that sync blocks aren’t “cleaned up” when a thread owns the monitor or when a thread is waiting for a monitor (which, in practice, means that you might end up leaking kernel objects if you don’t dispose the monitor when you’re done with it).

And I guess it’s all for today. Keep tuned for more on multithreading.

May 25

When we looked at the kernel objects, we’ve seen that we could use a mutex to achieve critical regions. Whenever we need to build a critical section, we should use the CLR locks instead of relying directly on mutexes. In .NET, any object can be used as a lock when you need to build a critical section. Entering the critical section is achieved through the static Monitor.Enter method. When you’re done, you should call the static Monitor.Exit method.

Here’s a quick example:

var locker = new Object(); //object used for locking
new Thread(() =>
{
    Monitor.Enter(locker);
    try {
        Console.WriteLine("thread 2 acquired lock at: {0}", DateTime.Now);
        Thread.Sleep(1000);
    } finally {
        Console.WriteLine("thread 2 released lock at: {0}", DateTime.Now);
        Monitor.Exit(locker);
    }
}).Start();

Monitor.Enter(locker);
try {
    Console.WriteLine("main thread acquired lock at: {0}", DateTime.Now);
    Thread.Sleep(1000);
}
finally {
    Console.WriteLine("main thread released lock at: {0}", DateTime.Now);               
    Monitor.Exit(locker);
}

As you can see, we’re calling the Enter method to enter the critical region of code and, when we’re done, we’re exiting the region by calling the Exit method. If you run the previous snippet,you’ll see that the one thread will only enter after the other has released the lock. Since the previous pattern (Enter/try/finally/Exit) is so much used,C# supports a shortcut for it through the use of the lock keyword:

var locker = new Object();
new Thread(() => {
    lock(locker){
        Console.WriteLine("thread 2");
    }
}).Start();

lock(locker){
    Console.WriteLine("main thread"); Thread.Sleep(1000);
}

Even though you can “lock” in any object (we’ll look at some code in the next paragraphs), it’s important to keep in mind that you should only use “private” objects. If you leak the “locked” object, you may be letting others interfere with your critical section (it’s no longer yours since anyone can use it for their own locks). This is especially true if you’re building libraries that will be reused by others…

That’s why it’s a bad idea to lock on this, public fields, value types (completely wrong since you’ll be getting “boxed” copies of the value type and this means that each thread will happily enter the critical sections since they’re using different objects for the lock), type objects and appdomain agile objects.Here’s a quick example that shows how things might go wrong when you leak the “locked” object. Suppose you have locker object is exposed from your library and is also used internally for achieving a critical section:

//supose locker and DoSomething are exported
//from your library
static Object locker = new Object();
static void DoSomething() {
    new Thread(() =>
    {
        Thread.Sleep(500); //ensures main thread enters the lock 1st
        lock (locker) {                   
            Console.WriteLine("thread 2");                   
        }
    }).Start();
}
static void Main(string[] args) {
    DoSomething();   
    Console.WriteLine("main thread dealocks the other");
    Monitor.Enter(locker);
    Console.WriteLine("end main");
}

I’ve just locked the program! Yes, I didn’t follow the recommendation of releasing the lock after ending it, but that was the easiest way of showing how your library code (simulated by the DoSomething method and shared locker object) might block if you start sharing the objects you lock on. As a general rule, you should only lock in private objects.

Besides the Enter/Exit method, the Monitor class exposes a third static method which you can use to avoid blocking: I’m talking about the TryEnter method. The class offers several overloads of these method (some let you pass a value for a timeout) and all of them return a boolean. When it returns true, you’ve acquired the lock successfully. If you pass 0 for the timeout (or use the overload which doesn’t let you specify the timeout), the method returns immediately and you should check its return value to see if you’ve acquired the lock.

The other overloads will block by the time you specify or until they acquire the lock. Notice that you cannot use the C# lock sugar for spinning (ie, for calling Monitor.TryEnter) and you’ll have to go with the try/finally approach we’ve seen earlier.

The TryEnter method is especially good when you have other things to do before entering the critical section:

new Thread(() => {
    lock (locker) {
        Console.WriteLine("thread 2 is busy!");
        Thread.Sleep(500);
    }
}).Start();
Thread.Sleep(100);
while (!Monitor.TryEnter(locker, 100)) {
    Console.WriteLine("Doing something else");
    Thread.Sleep(100);
}
try {
    Console.WriteLine( "entered critical section" );
}
finally{
    Console.WriteLine("exited critical section");
    Monitor.Exit(locker);
}

If you run the previous code, you’ll see that it will spin writing “Doing something else” until it enters the critical section. And that’s it for today. Keep tuned for more on CLR locks.

May 24

Multithreading: synchronization primitives

Posted in Multithreading       Comments Off on Multithreading: synchronization primitives

In the latest posts, we’ve taken a look at several kernel objects which we can use for data and control synchronization. Today we’re going to start looking at the synchronization primitives. These structures should always be used (whenever possible, of course) instead of the kernel objects we’ve met in previous posts. Why? Because they’re cheaper.

Why cheaper? well, the truth is that the kernel objects we’ve looked at in previous posts will always incur in kernel transitions (needed for accessing the internal structures they use). On the other hand, the primitives we’re going to look at in the next couple of posts tend to allocate kernel objects only when they’re needed (ie, they use a lazy allocation algorithm). What this means is that you’ll use them in user mode and you’ll only incur into kernel transitions when you really have to wait for something. Here are the primitives we’ll be looking at:

  • locks: in .NET, you’ll acquire a lock by using the Monitor.Enter method and you leave one by invoking the Monitor.Leave method. There’s also a TryEnter method which you can use to try to acquire the lock;
  • reader/writer locks: allow several threads to read while only allowing one the write. In .NET there are two classes you can use whenever you need this kind of locks: ReaderWriterLock and ReaderWriterLockSlim (the last is the preferred option);
  • condition variables: in .NET, you have access to these type of primitive through the Wait, Pulse and PulseAll methods of the Monitor class. Condition variables allow you to have one or more threads waiting for an occurrence of a specific event.

On the next posts we’ll take a deep dive into each of these options. Keep tuned for more!

May 22

Multithreading: signaling and waiting

Posted in C#, Multithreading       Comments Off on Multithreading: signaling and waiting

In the last post, we’ve talked about several methods that allow us to wait on one or more kernel objects until they transition into the signaled state. Today we’re going to take a look at the last method (exposed by the WaitHandle class) that we can use for waiting on an object: the SignalAndWait method. You can use one of the overloads of this method when you need to signal an existing kernel object and wait on another one until it gets into the signaled state. The coolest thing about this method is that the signaling and waiting is performed atomically! Signaling the object performs the expected operation:

  • if we have a mutex, it will call the ReleaseMutex method. Notice that if the mutex has been acquired recursively, then this will decrement the internal count by one;
  • if we have a semaphore, this method ends up calling ReleaseSemaphore;
  • finally, if it’s an event, we end up calling the Set method.

It’s also important to keep in mind that you might end up getting exceptions. For instance, if you’re calling this method and you’re signaling a semaphore that is already “full”, then you’ll end up getting and InvalidOperationException.

Whenever you need to signal a kernel object and wait on another, you should always use this method to ensure that the operations are performed atomically.

And that’s all for today. On the next post we’ll start looking at the high level sync primitives. Keep tuned for more.

May 21

Multithreading: waiting on kernel objects

Posted in C#, Multithreading       Comments Off on Multithreading: waiting on kernel objects

Until now, we’ve seen how we can wait on several synchronization kernel objects until a specific condition is met. All the examples we’ve seen ended up using the simple WaitOne method.Today we’re going to take a look at the other “waiting” methods inherited from the base WaitHandle class: WaitAny and WaitAll.

You’ll need these static methods whenever you need to wait on several kernel objects. WaitAll will only unblock when all objects have reached the signaled state; WaitAny will unblock when one of the handles the current thread is waiting on transitions to the signaled state. There are several overloads of these methods, which let you specify timeouts in several formats.

The WaitOne and WaitAll methods return a boolean: you’ll get true when the methods return as a result of the object being signaled or false if it returns as a consequence of the timeout. WaitAny has a different behaviour because it returns an integer (which indicates the handle which was signaled and unblocked the thread). When a timeout occurs, WaitAny ends up returning the constant WaitHandle.WaitTimeout (258).

The next snippet tries to show how you can use the WaitAll method to wait on several kernel objects:

var evt1 = new AutoResetEvent(false);
var evt2 = new AutoResetEvent(false);
var evt3 = new AutoResetEvent(false);         
new Thread( () => {
    Console.WriteLine( "Thread {0}", Thread.CurrentThread.ManagedThreadId );
    Thread.Sleep(2000);
    evt1.Set();
}).Start();
new Thread( () => {
    Console.WriteLine( "Thread {0}", Thread.CurrentThread.ManagedThreadId );
    Thread.Sleep(1000);
    evt2.Set();
}).Start();
new Thread( () => {
    Console.WriteLine( "Thread {0}", Thread.CurrentThread.ManagedThreadId );
    Thread.Sleep(1000);
    evt3.Set();
}).Start(); 
WaitHandle.WaitAll( new[]{ evt1, evt2, evt3 } );
Console.WriteLine("Ended wait");

Now, you could also change the code so that the main thread will only wait until one of the events gets signaled:

//previous code is the same
var pos = WaitHandle.WaitAny( new[] { evt1, evt2, evt3 });
Console.WriteLine("Ended wait. Evt in position {0} as signaled",pos);

In this case,you’ll get the position of the signaled kernel object in the array you’ve passed into the WaitAny method.

You should also keep in mind that you might end up getting exceptions when you call these methods (think abandoned mutexes and Interrupt calls!), so you’ll probably want to use them inside a try/catch block. As you can see, using these methods isn’t really that complicated. There’s still one very interesting method used for waiting that we still haven’t looked at: I’m talking about the SignalAndWait. We’ll talk about it in the next post.

May 20

Multithreading: “interrupting” threads waiting

Posted in C#, Multithreading       Comments Off on Multithreading: “interrupting” threads waiting

Ok, now that we’ve seen the basic kernel synchronization objects that you can use in .NET programming, I guess that it’s a good time to talk about how we can wake up a waiting thread without signaling the kernel object on which the thread is waiting for.

In .NET, any blocked thread can be awakened by calling the Thread.Interrupt method. For instance, take a look at the following example, where we create a thread and then make it go to sleep:

var anotherThread = new Thread(() => {
                Console.WriteLine("thread started");
                try {
                    Thread.Sleep(5000);
                }
                catch (ThreadInterruptedException ex) {
                    Console.WriteLine(ex.ToString());
                }
            });
anotherThread.Start();
anotherThread.Interrupt();

As you can see, whenever we suspect that someone will wake up the thread by calling the Interrupt method, we must also wrap the call that blocked the thread in a try/catch block (if we intend to do something when the thread awakes up). Even though I’ve decided to go with a sleep example, don’t forget that you can also use this with a thread that is waiting on a kernel object to become signaled or with a thread that is waiting on another thread (ie, has called the Join method).

Now that you know that the method exist, you should probably forget about it. If you’re writing general .NET code, then there really isn’t any way for you to know (for sure) what a thread is doing. And if you’re using 3rd party assemblies,then I’d say that you can’t really know if that assembly is prepared for handling this kind of exceptions…

Two important things you should know:

  • if the thread isn’t blocked,then the exception will only be thrown when it gets blocked (if it never gets blocked, then the exception will never be thrown);
  • thread interruptions aren’t processed if the thread is in a catch or finally block.

Just to test the last point, you can change the code to something like this:

var anotherThread = new Thread(() => {
    Console.WriteLine("thread started");
    try {
        throw new Exception();
    } catch (Exception ex) {
        Console.WriteLine("in catch");
        Thread.Sleep(5000);
        Console.WriteLine("out");
    }
});              
anotherThread.Start();
Thread.Sleep(1000);
anotherThread.Interrupt();
Thread.Sleep(1000);

As you can see, you won’t get any exception thrown when the thread that is being interrupted is waiting inside a catch block. And that’s all for today. Keep tuned for more on this topic.

May 19

[If you’ve just seem a one post sentence, then you’re probably seeing the first Luna’s post :,,) . She has just managed to publish a one line post while I was checking what was on the TV:)]

In the previous post, we’ve taken a quick glance at how we can use the ManualResetEvent. At the time, I did promise another example which might better illustrate its use. So, let’s suppose that we have a class that needs to perform a lengthy operation to initialize a field. Using a ManualResetEvent might be just what the doctor would order (if he could prescribe something for our multithreaded problems 🙂 ). Let’s start by looking at the class code:

class SlowInitializer {
    private String _someInfoThatIsExpensive;
    private ManualResetEvent _evt = new ManualResetEvent(false); //non signaled
    public String SomeInfoThatIsExpensive {
        get {
            _evt.WaitOne();
            _someInfoThatIsExpensive = DateTime.Now.ToString();
            return _someInfoThatIsExpensive;
        }
    }
    public SlowInitializer() {
        new Thread(() => {
            Console.WriteLine("Starting expensive operation at " + DateTime.Now.ToString());
            Thread.Sleep(2000);
            Console.WriteLine("Ended expensive operation");
            _evt.Set();
        }).Start();
    }
}

As you can see, we have a simple class which needs to perform a lot of work (not sure about you, but sleeping is a lot of work sometimes) to initialize the _someInfoThatIsExpensive field. In this case, we’re using an event to ensure that a consumer will only have access to the field *after* it has been properly initialized. Initialization is performed in the constructor and it’s delegated to another thread (ensuring that the thread where the instance is created will only block if it accesses the SomeInfoThatIsExpensive property before initialization is completed). Suppose you have the following code:

var slow = new SlowInitializer();           
new Thread(
    () => Console.WriteLine(DateTime.Now.ToString() + "- " + slow.SomeInfoThatIsExpensive))
    .Start();
new Thread(
    () => Console.WriteLine(DateTime.Now.ToString() + "- " + slow.SomeInfoThatIsExpensive))
    .Start();
Console.WriteLine(DateTime.Now.ToString() + "- " + slow.SomeInfoThatIsExpensive);
Thread.Sleep(1000);
new Thread(
    () => Console.WriteLine(DateTime.Now.ToString() + "- " + slow.SomeInfoThatIsExpensive))
    .Start();

If you try to run the previous snippet, you should get blocked on the Console.WriteLine that precedes the Thread.Sleep (btw, that Thread.Sleep is only there to show you that the last thread has direct access to the property – ie, it won’t get blocked because the event has already transitioned into the signaled state). The following figure shows the results I got on my machine:

manualreset

Notice the time of execution for the several Console.WriteLine instructions…As you can see, this is a good scenario for the ManualResetEvent type. And that’s all for today. Keep tuned for more on multithreading! (as you can see, I’m still learning, but I’m already hooked on this fascinating topic! 🙂 )

May 19

Multithreading: ManualResetEvent events

Posted in C#, Multithreading       Comments Off on Multithreading: ManualResetEvent events

Yesterday we’ve taken a peek at the AutoResetEvent. Today, we’re going to keep looking at kernel objects and we’ll see how we can use the ManualResetEvent for synchronization purposes. I guess that the easiest way to show them doing some work is by going straight to the code.

Yesterday we’ve taken a look at a really dumb sample that showed the behavior of the AutoResetEvent class. Today, we’re porting (sort of) that sample so that it uses the ManualResetEvent class:

using (var evt = new ManualResetEvent(false)) {   
    var threads = Enumerable.Range(0, 2)
        .Select(i => new Thread(() => {
                                        evt.WaitOne();
                                        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                                    }))
        .ToList();
    foreach (var thread in threads) {
        thread.Start();
    }
    Console.WriteLine("Fired threads");
    Thread.Sleep(200);
    evt.Set();
    Console.ReadLine();
}

As you can see, we start by creating a new ManualResetEvent in the non signaled state. Then, we create and start two threads which block until the event is set. As you can see, we don’t need to set the event in the secondary threads (like we did in yesterday’s sample). That happens because the event isn’t automatically reset after it has been set. If we needed that, then we would need to call the Reset method. Unfortunately, I’m out of time to present a more interesting sample, but I’ll return to the topic in a future post. Keep tuned.

May 18

Multithreading: using AutoResetEvents

Posted in C#, Multithreading       Comments Off on Multithreading: using AutoResetEvents

After the introductory theory associated with events, it’s time to take a look at how we can use an AutoResetEvent for synchronizing access to a protected resource. The first thing we need to do to start using an AutoResetEvent is getting a reference to a valid instance of this type. We can get one by calling one of the constructors or one of the several overloads of the OpenExisting method:

//create new
public EventWaitHandle(bool initialState, EventResetMode mode);
public EventWaitHandle(bool initialState, EventResetMode mode, string name);
public EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew);
public EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew, EventWaitHandleSecurity eventSecurity);

//get valid reference for existing event
public static EventWaitHandle OpenExisting(string name);
public static EventWaitHandle OpenExisting(string name,EventWaitHandleRights rights);

As we’ve seen,AutoResetEvent don’t have the concept of ownership. This means that one thread can Set the event and another Reset it. Take a look at the following code:

var evt = new AutoResetEvent(false);//not signaled
new Thread(() => {
                     evt.WaitOne();
                     Console.WriteLine("Entered thread1");
                     evt.Set();
                 }).Start();
new Thread(() => {
                    evt.WaitOne();
                    Console.WriteLine("Entered thread2");
                    evt.Set();
                }).Start();
Console.WriteLine("Fired threads");
Thread.Sleep(200);
new Thread(() =>{ evt.Set();}).Start();
Console.ReadLine();

Granted: this doesn’t really do anything useful, but it shows how things work when you use an event. As you can see, we start by creating a new AutoResetEvent which is in the non-signaled state. That means that the two new created threads will block until the main thread wakes up and starts another thread, which is responsible for setting the event (and allowing the wakening of one of those blocked threads).

By setting event, the AutoResetEvent will transition *automatically* to the non signaled after another waiting thread is waken up and starts doing its work (ie, you don’t have to call Reset for it to go back to the non-signaled state).

Joe Duffy points out an important detail about events and priority boosts. According to Joe, a thread that is waiting on an event sees its priority boosted to 1 whenever it is wakened. Generally, this is ok, but it might lead to some undesired scenarios where the thread that sets the event holds to a resource that the waiting thread will need.

So, as you can see, using an AutoResetEvent isn’t really that difficult from using the other kernel objects we’ve met in previous posts: first you need to get a reference by creating a new object or getting a reference to a previously named object; then you wait on it by calling one of the WaitXXX methods; finally, you allow another thread to wake up and do its work by signaling the object through a Set method call.

On the next post, we’ll take a look at the ManualResetEvent class. Keep tuned.

May 18

Multithreading: using events

Posted in C#, Multithreading       Comments Off on Multithreading: using events

Windows OS offers two kinds of events: auto and manual-reset events. As you might expect by now, any event can be in a signaled or non-signaled state (after all, both of these events are kernel objects). Instead of using signaled and non-signaled terms, you’ll probably hear the words set and reset when talking about these states.

The main difference between auto and manual-reset events relies on the fact that an auto-reset event will automatically reset itself. Notice also that when you use an auto-reset event, only one thread will be awakened (if there are any waiting for the event to be set; if there aren’t, then the auto-reset event object will remain signaled until another thread acquires it).

After reading the previous paragraph, you might think that an auto-reset event exhibits a similar behavior to the one you get when you use a mutex. Even though that is true (you have only one thread accessing the protected resource at a time and only one will be wakened when the event is set), it’s important to understand that events don’t have the concept of ownership. In practice, this means that you wont be able to have recursion (which might be good thing). In practice, this means that you can set the event from any thread (ie, you don’t need to set if from the thread that created the event).

Manual-reset events work in a slightly different way. When a manual-reset event is set, it will remain set until some thread resets it. This means that several waiting threads will be awakened when the object is in the signaled state. Manual-reset events are good for what I call event-based scenarios,where you need to signal several waiting threads that something has happened.

events

As you can see from the previous model,AutoResetEvent and ManualResetEvent lets you work with events from managed code. You can also see (from the model) that both classes shared the same base class (EventWaitHandle) which isn’t abstract. In fact, if you dig into the code, you’ll notice that AutoResetEvent and ManualResetEvent are there only for passing the correct values to the base EventWaitHandle’s constructor (so, if you want, you can use directly the EventWaitHandle class in your code, though that is not a general accepted practice).

Working with these kernel objects is similar to the ones we’ve seen before and I’ll leave the code for the next posts (I’m trying to write only short posts from now on because they’re easy to read and digest). Keep tuned for more!

May 17

In the previous post we’ve seen several concepts associated with semaphore usage. In this post we’re going to see some code that shows how to use this synchronization kernel object. Creating a new semaphore is accomplished through one of the existing constructors:

public Semaphore(int initialCount, int maximumCount);
public Semaphore(int initialCount, int maximumCount, string name);
public Semaphore(int initialCount, int maximumCount, string name, out bool createdNew);
public Semaphore(int initialCount, int maximumCount, string name, out bool createdNew, SemaphoreSecurity semaphoreSecurity);

Whenever you create a semaphore, you need to initialize its initial and maximum allowed count. These values might be a little confusing,so I think it would be wise to describe them a little better before going on…initialCount is used for initializing the internal counter used by the sempahore. On the other hand,maximumCount defines the maximum number of threads that can acquire the resource protected by the semaphore without blocking (after maximumCount has been reached, all threads will block whenever they try to acquire the protected resource). Passing different values for these properties is the same thing as having the current thread call WaitOne maximumCount-initialCount times. Take a look at the following instantiations:

(1) var semaphore = new Semaphore(0, 2);
(2) var semaphore = new Semaphore(2, 2);

On (1), the next thread that performs a take (ie, that calls WaitOne) over the semaphore will block; on the other hand, (2) lets you call WaitOne twice before blocking the thread that performs the next call.

Since there isn’t the concept of ownership, nothing prevents you from calling Release from a thread that didn’t acquire the semaphore. You can even use the overload that accepts an integer that indicates the number of times you’re releasing the semaphore. In practice, this means that Release bumps up the internal counter, allowing other threads that were blocked to awake up. You need to be sure that you don’t go over the maximum value allowed (passed to the semaphore through the constructor) or you’ll get an exception.

Everything we’ve said about *named* mutexes is also true for semaphores (ie, when you create a named semaphore, you might be getting a new semaphore or an existing semaphore – you need to check the createdNew parameter to see what has happened after that call). Ok, I guess it’s time to take a look at some code. The following is a possible implementation of a concurrent stack where we allow several consumers and producers to add and remove elements concurrently from the queue. Here is the code*:

class ConcurrentStack<T> {
    private Stack<T> _stack = new Stack<T>();
    private Mutex _lock = new Mutex();
    private Semaphore _producer;
    private Semaphore _consumer;
    public ConcurrentStack(Int32 maxCapacity) {
        _producer = new Semaphore(maxCapacity, maxCapacity);
        _consumer = new Semaphore(0, maxCapacity);
    }
    public T Pop() {
        _consumer.WaitOne();
        T element;
        _lock.WaitOne();
        try {
            element = _stack.Pop();
        }
        finally {
            _lock.ReleaseMutex();
        }
        _producer.Release();
        return element;
    }
    public void Push(T element) {
        _producer.WaitOne();
        _lock.WaitOne();
        try {
            _stack.Push(element);
        }
        finally {
            _lock.ReleaseMutex();
        }
        _consumer.Release();
    }
}

As you can see, we’re not using the semaphore for achieving mutual exclusion (that’s the job of the mutex, which is there for ensuring proper mutual exclusion for the queue access). In this case, we’re using semaphores for controlling the number of pops and pushes that can happen at a specific time. As you can see, there are two semaphores: one for consumers (which control the number of concurrent pop instructions that can happened) and another for producers (that control entry on the Push method). The previous code ensures that a thread that tries to add an item to a stack that has maxCapacity elements is blocked (the same happens for a thread that tries to remove an element from an empty stack).

Notice that acquiring and releasing operations are performed in different methods (compare this behavior with the mutex’s behavior!). Whenever we pop an element, we take one from the consumer’s semaphore and then we call Release over the producer’s semaphore, leading to a possible wake of a thread that might have been previously blocked. The inverse principle is followed by the Pop method.

Now we can simply create several consumer and producer threads. Here’s some code that does that:

var stack = new ConcurrentStack<Int32>(2);
var consumerThread1 = new Thread( () => { Console.WriteLine( stack.Pop() ); });
var consumerThread2 = new Thread( () => { Console.WriteLine( stack.Pop() ); });
var producerThread1 = new Thread(num => { stack.Push((Int32)num);});
var producerThread2 = new Thread(num => { stack.Push((Int32)num); });
consumerThread1.Start();
consumerThread2.Start();
producerThread1.Start(2);
producerThread2.Start(10);

If you run this program, you’ll notice that the consumers will block until there are elements on the stack. I think that this simple example is good for showing the things at which semaphores are good at. And that’s it for today. On the next post, we’ll be talking about auto and reset events. Keep tuned!

* heavily influenced by Joe Duffy’s Concurrent Programming on Windows excellent book.

May 15

Multithreading: Semaphores

Posted in Multithreading       Comments Off on Multithreading: Semaphores

This post is all about theory…you’ve been warned :,,)

Semaphores have different usage semantics than mutexes. A thread can perform two operations over a semaphore: you can run a put or a take. Internally, the semaphore maintains a count of the numbers of takes and puts through the use of a counter: whenever a thread tries to take take from a semaphore, it will succeed and decrement the counter *if*, at that moment, the counter is bigger than 0. Putting performs the reverse operation. Both operations (put and take) are atomic.

As you might expect, you can “set up” the counter whenever you create a new semaphore, limiting the maximum number of threads which can simultaneously access the resource protected by that semaphore. Since a semaphore is also a kernel object, the same principles that we’ve talked about in the past still hold. A semaphore is signaled whenever its internal counter’s value is non zero. A semaphore is in the non signaled state whenever the it reaches 0. Trying to take from a non signaled semaphore (ie, “acquiring” from a semaphore where its internal counter is 0) blocks until the counter is increased (which will only happen when another thread performs a put operation – or, if you prefer the acquire/release terminology, when another thread releases the semaphore).

Unlike mutexes, semaphores don’t support the concept of ownership. This means that you can have a thread putting and other taking (without having put before). Like mutexes, semaphores will only wake as many threads as the ones that can “acquire” the semaphore (ie, if you’ve got 4 threads blocked  and the semaphore’s counter has seen its value pop up to 2, then only the first 2 threads will be awakened) – recall that mutexes will only wake a single thread at a time.

In the “real world”, you’ll tend to use semaphores when you need to protect access to finite resources. A good example of the kind of resources protected by a semaphore are pools (of objects), where you can only allow x threads at a time. Publisher/subscriber scenarios are also scenarios that might benefit from using semaphores.

Ok, I guess that this is more than enough for an introduction to this topic. The next post will present some code snippets of its usage.

May 15

Multithreading: “sharing” mutexes

Posted in C#, Multithreading       Comments Off on Multithreading: “sharing” mutexes

In the previous post, we’ve looked at some important features provided by the Mutex kernel object. Today we’re going to keep looking at mutexes and we’ll take a look at how we can create named mutexes and use them for synchronizing access to shared state.

true that using kernel objects has costs: when you wait, you’ll always incur in a context switch, which really translates into several “wasted” CPU instructions. But it’s also true that it facilitates other scenarios that the other high level primitives can’t handle. As we’ve seen in the previous post, the Mutex class offers several constructors. Several of them allow you to pass a name and return a reference to a new (or existing) named mutex. It’s

Whenever you create a named kernel object, you can recover that object by its name. This means that you can use it for (and this is just an example) interprocess synchronization. It’s also important to keep in mind that you should probably secure a named kernel object so that you can limit the people that can access and use it.

To illustrate some of its potential, we’re going to write  a simple console app that lets you run only one instance at a time. When using a mutex for this we have several approaches. Here are some of them:

  • we can wait on  a mutex and return imediately by passing 0 to one of the WaitOne method overloads that receive a timeout;
  • we can try to call the static OpenExisting method to see if there already exists with the predefined name. The method throws a WaiHandleCannotBeOpenedException when it can’t find a kernel object with that name;
  • we can skip waiting entirely if we use the constructor that has an out created parameter.

Ok, lets see how we can implement these options. I’m going to start from option1. Here’s some code that tries to use that approach:

var mutex = new Mutex(false, "test");
try {
   if( !mutex.WaitOne(0, false) ) {
      Console.WriteLine("Can only run one application instance");
      return;
    }
  }
  catch (AbandonedMutexException) {
    //ok, there”s probably some clean up here
    //because even if you kill the process on task manager, 
    //you won”t get this when you run the app again
    //check this post http://ayende.com/Blog/archive/2008/02/28/The-mysterious-life-of-mutexes.aspx
    Console.WriteLine("Previous app wasn”t closed correctly");
    mutex.Close();
    return;
  }
  try{
     while (Console.ReadKey().Key != ConsoleKey.X) {
        Console.WriteLine();
     }
  }
  finally{
     mutex.ReleaseMutex();
  }
  mutex.Close();

If you recall it,calling one of the WaitXXX methods might throw an exception because we might have an abandoned mutex. Interestingly,you won’t be getting this exception with the console sample (even if you kill the managed process by using task manager and skip the cleanup). The docs don’t mention anything about this behavior, but it does really look like the CLR is cleaning up for you (if you try abandoning a mutex on a thread and then reacquiring it on another on the same app then yes, you’ll get the exception!). Btw, I’ve found an post by Ayende where a comment refers this behavior. Despite that, I decided to wrap the WaitOne call because I think that doing this is a recommended practice (after all, we can’t know if this behavior will change in the future).

Going back to our list, we can see that option 2 relies on the OpenExisting static method. In this case, we don’t even need to acquire the mutex by waiting on it:

Boolean exists = false;
Mutex mutex = null;
try {
      mutex = Mutex.OpenExisting("test");
      exists = true;
}
catch (WaitHandleCannotBeOpenedException) {
     mutex = new Mutex(false, "test");
}
if(exists) {
      Console.WriteLine("Can only run one application instance");
      return;
}
while (Console.ReadKey().Key != ConsoleKey.X) {
   Console.WriteLine();
}
mutex.Close();

Option 3 is just a variation of this approach:

Boolean created;
var mutex = new Mutex(false, "test", out created);
if( !created ){
    Console.WriteLine("Can only run one application instance");
    return;
}
while( Console.ReadKey().Key != ConsoleKey.X){
    Console.WriteLine();
}
mutex.Close();

ok, I guess that it’s all for today. I’m sure there are lots of things you can do with this kernel object, but I guess that these and yesterday’s post should give you several hints on how to use it.

Keep tuned for more on multithreading…

May 14

Ok, now that we understand the basics of waiting on a kernel object, it’s time to keep going and start looking at some code (hurray!). Today we’re going to take a look at the mutex kernel object. In .NET, a mutex kernel object is represented by an instance of type Mutex. As we’ve seen yesterday,  the Mutex type sublcasses the WaitHandle type.

In practice, we use mutexes to build critical regions, ie, to delimit certain regions of code so that they can only be executed by a thread at a time. Since a mutex is a kernel object, you’re right if you’re thinking that mutual exclusion is achieved through atomic state transition (signaled to non signaled).

When a mutex is in a signaled state, it can be taken by any thread that enters the region delimited by it. When that happens, the mutex transitions to the non signaled state and the thread that entered that critical region owns the mutex (this is an important concept that you should keep in mind – notice that not all kernel objecs have the concept of ownership). All other threads that try to enter the critical region will be blocked.

When a thread that owns a mutex exits a critical region, it must always signal that in order to release ownership so that other threads can be awakened and enter that region. In practice,entering a critical region is done by waiting on a mutex and leaving a critical section consists (simply) on releasing it (as we’ll see in the snippet I’m showing below).

Since mutexes support the concept of ownership,it’s interesting to try to understand what happens when a) you forget to call release on a mutex, b) you have reentrancy (that is, a thread that has already acquired the mutex acquires it again before releasing it) and c) you call release on a mutex you don’t own.

Lets start with scenario a), which is generally know as abandoned mutex. Since a mutex is a kernel object, when a mutex is abandoned (ie, when a thread that owns it terminates and doesn’t release it), we can count on the OS to help us. If the OS detects an abandoned mutex and sees that it has waiting threads, it will wake one of them as if the mutex had been released and, in the case of managed code, it will throw an AbandonedMutexException exception. Notice that even though it throws, the new thread that was awaked acquires the mutex successfully (which means that you need to be prepared for this and you shouldn’t forget to release the mutex at the end of the critical region). Even though you can recover from this exception, you probably should proceed with caution because an abandoned mutex might indicate some unknown error in your program.

Now, what happens when you have reentrancy? Well, it will succeed because mutexes support the concept of ownership and use an internal field for keeping track of the number of the times the owner thread has waited  on it (recall that waiting will succeed immediately when a mutex is signaled or when the “current” thread owns that mutex). The only thing you should keep in mind is that if you acquire a mutex several times, then you must pair those acquisitions with release calls.

Releasing a mutex (option c) can only have one result: an exception will be thrown.

Ok, enough theory…time so show some code. The first time you need to do is to create a mutex. In .NET, you can do that by using one of the following constructors exposed by the Mutex type:

public Mutex();
public Mutex(bool initiallyOwned);
public Mutex(bool initiallyOwned, string name);
public Mutex(bool initiallyOwned, string name, out bool createdNew);
public Mutex(bool initiallyOwned, string name, out bool createdNew, MutexSecurity mutexSecurity);

As you can see, we have several options. The default constructor creates a new mutex in a signaled state. If that is not what you want, you should use one of the overloads which receive the initiallyOwned parameter (passing true to this results in getting a non signaled mutex owned by the thread).

The overloads that receive a name let you set the mutex name (kernel objects can be named which means that they can easily be shared across processes. We’ll come back to this topic in the future). There are also a couple of overloads with an out parameter. These are useful when you need to know it the created mutex is really a new mutex (when you try to create a named mutex and there’s already one with that name, the constructor will return a reference to that instance. In this case, the createdNew will let you know if the returned mutex already exists).

Finally, the overload that receives a MutexSecurity parameter lets you set up the ACL for this kernel object. There are a couple of possible results from all these combinations and I’ll return to them in a future post.

As we’ve seen, we acquire a mutex by calling one of the WaitXXX methods and we should also signal the exit of the critical region by calling ReleaseMutex (notice that this *might* release the ownership of the mutex and let other threads enter the region).

When we’re really done with the mutex, we’re supposed to close it by calling Close or Dispose (recall that WaitHandle implements the IDisposable interface). Ok, here’s the dumbest example I could write in 30 seconds to show the usage of these methods:

static void Main(string[] args) {
   Thread secondary;
   var mutex = new Mutex();//owned signaled mutex
   mutex.WaitOne();
   try {
      secondary = new Thread(() => {
                                     mutex.WaitOne();
                                     try
                                     {
                                         Console.WriteLine("secondary thread");
                                     }
                                     finally
                                     {
                                         mutex.ReleaseMutex();

                                     }
                                 });
       secondary.Start(); //will wait for release of main
       Console.WriteLine("Primary thread");
    }
    finally {
       mutex.ReleaseMutex();
    }    
    secondary.Join();
    mutex.Close();
  }
}

A couple of observations for the previous code:

  • we start by creating a new signaled unnamed mutex owned by the main thread and we acquire it immediately by calling the WaitOne method.
  • we use a try/finally block to ensure that the mutex is released. This ensures that the secondary thread gets a chance for running;
  • we close the mutex by invoking the Close method. This is important and it ends up releasing the OS mutex kernel object encapsulated by the managed Mutex instance.

There are still a couple of cases I think are worth showing, but I’ll leave them for future posts. Keep tuned for more on multithreaded apps!

May 13

After a short break, I’m back for more on multithreading. In the last post, we’ve talked a little bit about synchronization. Today we’re going to keep talking about it and we’re going to take a quick look at how we can use kernel objects for synchronizing access to shared resources or to control the execution of a specific code zone. Initially, I though in going straight to the high level synchronization structures, but since they might end up delegating in these kernel objects, I thought that a quick intro wouldn’t hurt,right?

Ok, so lets concentrate on the basics…There are several kernel objects which are exposed through several different APIs. In traditional Win32, each kernel object is represented by a HANDLE (which you typically need to close after you’re done with it). Each kernel object can be in one of two states: signaled and non signaled. Transition between these states depend on the specific type of kernel object we’re using. For instance, an OS thread is represented by a Thread Kernel object (represented in Win32 as a HANDLE) and it transitions from the non signaled state to the signaled state when the thread is terminated (and, as we’ve seen, the recommended way for a thread to terminate is by letting it run all the code to the end).

If we want,we can make a thread wait on any kernel object until it gets signaled. In practice,this means that we can make a thread block until the kernel object is signaled (notice that we can make several threads wait on a single kernel object). When this happens and a thread blocks, there’s a context switch and the thread is removed from the processor. When the kernel object the thread is waiting on transitions to the signaled state, the thread might (or might not) be awaken: it all depends on the type of the kernel object (some will wake only a single thread while others end up waking several threads – we’ll come back to this when we talk about the concrete synchronization objects).

Now is a good time to mention that in this series of posts we’re only interested in waiting on the synchronization kernel objects (ok, we can wait on any kernel object, but typically we’ll be waiting on the synchronization objects): mutexes, sempahores, events (auto and manual) and timers. The .NET framework lets introduces a base class on which we can wait that is extended by mutexes, semaphores and events (there’s no direct support for timers). I’m talking about the the WaitHandle class, which is subclassed by the Mutex, Semaphore, AutoResetEvent and ManualResetEvent classes (these last two extend the EventWaitHandle class).

After getting a reference to a WaitHandle, we can use any of the overloads of the instance WaitOne methods to make the thread wait for the kernel object to get into a signaled state. We can also use the static WaitAll or WaitAny if we need to wait on several kernel objects to become signaled (the first method will block the thread until all the kernel objects passed into it get into the signaled state; the second will unblock when any of the kernel objects passed into transition to the signaled state).

After a thread gets blocked waiting for a kernel object to transition from the non signaled to the signaled state, it might wake up without the corresponding non signaled to signaled transition. This happens when the thread performs a so called “alertable wait” (in unmanaged code, you can control this, but in managed, threads always perform “alertable waits”). An thread that is blocked in an “alertable wait” might be awakened whenever it receives an APC call (which is dispatched automatically). Another interesting example where we might need to awake a blocked thread is when the thread created a window (and notice that you end up doing this whenever you instantiate  COM STA component). In this case, we need to pump the messages and that means that we need to “wake” the thread before the kernel object has performed its transition. Failing to do it means that we’ll end up with a non-responding window.

Whenever we wait on a managed WaitHandle, we end up getting an “alertable wait”. This means that CLR will end up pumping messages for you (at least, COM RPC messages). In my opinion, this is a good thing (just think about all those Win 32 methods you could use for waiting on a kernel object – for instance, there were WaitForSingleObjectEx, MsgWaitForSimpleObjectsEx, etc, etc, etc). Interestingly (or not), “alertable waits” end up complicating our code, especially when we need to wait and  need to specify a timeout. In managed code, the CLR takes care of everything and adapts the timeout if a thread is awaked before a kernel object transitions to the signaled stated. No such luck for the guys writing unmanaged code (yes, we managed programmers are spoiled!)

And I guess I’ll stop for today. When I started writing this post, I thought about showing a concrete example of the usage of one of the kernel objects, but as you can see, this is already a long post and I’ll defer the code for the next post. btw, if you’re interested in a more deep dive on this stuff, then you must really buy Joe Duffy’s master piece (review here) on writing concurrent apps for windows.

And that’s it for today. Keep tuned for more on multithreaded apps!

May 11

Today we’re going to start talking about an interesting and complex topic: synchronization. As we’ve seen in previous posts, and even though we should strive for having immutable objects, the truth is that shared state will always exist and this means that we need to synchronize access whenever we have several threads that need to access that state (from previous posts, we’ve seen that the only safe scenario for allowing access to shared state *without* synchronization is when we have several read only operations).

In practice, we can classify synchronization in two sub-areas:

  • data: this is probably the most used approach, where we need to ensure that only one thread accesses data at each time.
  • control: this approach is used when one thread depends on the other having executed some piece of code (think in publish/subscriber scenarios, where the subscriber waits for the data that is published by the publisher).

Obviously, you can mix both approaches in the same application.

The solution for controlling data access (data synchronization) relies on serializing access to shared state. This is achieved by creating *critical regions* that ensure mutual exclusion for a specific region of code. In practice, a critical region delimits several instructions which are executed  by a specific thread in a serialized fashion (ie, the critical region ensures that a second thread will only enter the region and execute the instructions delimited by it when the first thread has already executed them and left the critical region).

Currently, there are several mechanisms that we can use in order to get a critical region. For instance, many of us have already used Monitors for serializing access to a specific region of code (we’ll come back to this topic in future posts,when we start looking at some code that exemplifies the usage of this feature).

The usage pattern for a critical region is simple: a thread enters a critical region,executes several instructions and then leaves the critical region (assuming, of course, that we don’t have any exceptions and that the thread isn’t aborted). When another thread tries to enter that region, it will only succeed if the first thread has exited that region. If that hasn’t happened yet, then it will block and wait for the first thread to exit the region. In other words, critical regions normally have a scope!

There are several algorithms that can be used for supporting critical regions. Nowadays, most algorithms are built on a mixture of OS waiting support and the hardware atomic CAS (compare and swap).

Control synchronization is appropriate for scenarios where you need to ensure collaboration between several parties (and lets face it, this is needed in several cases). In this case, we’ll have an intervenient which needs to wait while some condition isn’t true. There are several approaches that can be followed for implementing the waiting part:

  • busy waiting:  this means that you’ll have an infinite cycle which will run until a specific condition is true. This might be a good approach for those cases where the thread can do some useful work while it waits for that condition. On the other hand, it’s not a good approach to follow when the thread is just there, spinning, without doing anything useful;
  • real wait: in this case, the OS kernel puts the thread in a real waiting state (this means that the thread won’t be consuming processor time, but we’ll have other costs related to thread switching);
  • continuation passing: this relies in passing a closure for being executed when another specific action ends. This might be a good option for those cases where waiting is too expensive. In this scenario, shared state is encapsulated in messages which are “passed” between threads.

And I guess that this a lot for one post. We’ll come back to this topic with some code samples.