May 2009 - Posts

Multithreading: queuing work items
Thu, May 28 2009 22:01

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.

by luisabreu | with no comments
Filed under: ,
VS 2010 color scheme patch
Thu, May 28 2009 21:05

If you enjoy dark themes and love VS 2010, then you know you’re into trouble. The problem is that VS looses the dark background after being closed and you need to go to the options, fonts and colors and then apply the current settings (which still have the correct color) again.

The good news is that is no longer necessary. You just need to install the background patch extension from the VS gallery.

thanks for the fix guys!

by luisabreu | with no comments
Filed under: ,
Downloading .NET reflector
Thu, May 28 2009 10:38

Not sure on how I should classify this, but I’d say that getting this error in 2009 from a page served by a company like redgate is incredible! Today I needed to download reflector, so I went to redgate’s site and chose the download option. When you do that, you’ll be redirected to a page that asks for name and email. Since I was in a hurry, I’ve just hit several keys in the keyboard and ended up introducing this:

error1

Notice the < on the email…then, clicking the download free copy produced the following result:

error2

fantastic, right?

by luisabreu | with no comments
Filed under:
Multithreading: introducing the thread pool
Wed, May 27 2009 19:48

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.

Using condition variables
Wed, May 27 2009 18:52

A few posts ago, we’ve seen how we could create a producer/consumer stack. Let’s update the example for using condition variables. Here’s the code:

class ConcurrentStack<T> {
    private readonly Object _locker = new Object();
    private readonly Stack<T> _stack = new Stack<T>();
    public void Push(T element) {
        lock (_locker) {
            _stack.Push(element);
            Monitor.Pulse(_locker);
        }
    }
    public T Pop() {
        lock (_locker) {
            while (_stack.Count == 0) {
                Monitor.Wait(_locker);
            }
            return _stack.Pop();
        }
    }
}

The first thing you should keep in mind is that you can only call Pulse or Wait (or PulseAll) when the calling thread owns the lock for the object. Not doing that means that you’ll get a SynchronizationLockException exception. The most interesting part of the code is the while cycle that wraps  the Monitor.Wait call. It’s there because when a thread is awaken in a condition, it won’t run immediately (so there’s always a chance that another thread might have been scheduled to run and has already pop the stack into an empty state).

And that’s all for today. In the next post, we’re going to explore our options for creating new threads (until now, we’ve been creating new threads explicitly).

by luisabreu | with no comments
Filed under: ,
Multithreading: condition variables
Wed, May 27 2009 16:01

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!

by luisabreu | with no comments
Filed under: ,
C question from Dan Garcia
Wed, May 27 2009 9:39

Currently, I’m following Dan Garcia’s CS61C course (which is freely available online). On lesson 6, there’s an interesting puzzle (which, btw, I got it wrong – I’ll tell you why on the next post). The question is: which snippets prints always 5?

1)
main() {
   int *a-ptr; *a-ptr = 5; printf(“%d”, *a-ptr);
}

2)

main() {
  int *p, a = 5;
  p = &a; ...
  /* code; a & p NEVER on LHS of = */
  printf(“%d”, a);
}

3)

main() {
int *ptr;
ptr = (int *) malloc (sizeof(int));
*ptr = 5;
printf(“%d”, *ptr);
}

Option 2 says that there’s code between p = &a; and the printf line, but a and p are never on the left hand sign of an equals operation. With this data, which option (if any) do you think will always print 5?

by luisabreu | with no comments
Filed under:
Sheer mind power!
Tue, May 26 2009 21:41

This is not a technical post, so if you’re not interested, just skip it!

Here’s the deal: a few days back, my good friend Filipe (aka, “super-loide” – long story, ok? but he knows why he’s called that:)) started laughing when I said that I would reach the 10km mark on my treadmill. His words: “You won’t make it”. I didn’t say nothing at the time, but I knew I’d make it. Generally, I run 2 to 3 times a week, for about 25 minutes (at a max of 4 kms a run).

I’ve already run 6 kms in the past and it was a painful experience (especially because I don’t enjoy running). I knew that achieving the 10km mark meant that I had to run at least an hour, at 10Km/h. This wasn’t going to be easy…

However, I do believe in the power of the mind (I’d say that’s why I believe in the “Yes, We can” slogan too). And today, while I’m on a terrible cold, I’ve decided to reach that mark! It’s crazy, right? I know, but, after all, if I can do it today, I’ll be able to do it any day! And here’s the proof:

IMG_2630

And here am I, after running 62 minutes (almost dead, but really happy for achieving the mark):

IMG_2633

Btw, you can see one of my secrets for achieving my objective: Nightwish’s End of an Era DVD! The other was my wife, which helped me made the last 500 meters :)

So now you have it “super-loide” :). If I can do it, you can too! It’s all in the mind…

by luisabreu | with no comments
Filed under:
Multithreading: reader/writer locks
Tue, May 26 2009 11:45

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.

by luisabreu | with no comments
Filed under: ,
Type parameters on Func delegates
Tue, May 26 2009 11:08

Eric Lipert has another very interesting entry which explains why the team decided to use the last type parameter as the return value of a Func compatible delegate. I think that Eric should put his thoughts on a book so that I could read everything all over again while I’m on the bus. What I’m saying is that this guy know so many things and writes so well that I guess that we would all benefit from a paper version of his blog :)

by luisabreu | with no comments
Filed under:
Multithreading: more on CLR locks
Mon, May 25 2009 19:57

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.

by luisabreu | with no comments
Filed under: ,
Multithreading: CLR locks
Mon, May 25 2009 11:34

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.

by luisabreu | with no comments
Filed under: ,
Multithreading: synchronization primitives
Sun, May 24 2009 21:03

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!

by luisabreu | with no comments
Filed under:
Multithreading: signaling and waiting
Fri, May 22 2009 11:12

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.

by luisabreu | with no comments
Filed under: ,
Multithreading: waiting on kernel objects
Thu, May 21 2009 14:26

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.

by luisabreu | with no comments
Filed under: ,
Multithreading: “interrupting” threads waiting
Wed, May 20 2009 12:08

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.
by luisabreu | with no comments
Filed under: ,
Wonderful news!
Tue, May 19 2009 21:58

Currently, I’ve got three wonderful cats. Luna, a cat that I’ve found in the street when she was two months old, got really sick in the last months…in fact, the vet had told us to get ready because her liver problems wouldn’t let her live much longer. All her blood tests returned some pretty bad figures…so bad, that the vet told us to forget her food diet and let her eat whatever she wanted.

And so we did…until that yesterday she stopped eating…we really thought the worst when we took her back to the vet again…however, it seems like she was, in fact, much much better (even though she wasn’t eating). After running some more tests, we got confirmation: she is, in fact, much better and she’ll probably get her appetite back in a few hours. As you can probably guess, this news has made me a really happy man! And I think that it’s time to get away from the PC and enjoy some time with my pets :)

by luisabreu | with no comments
Filed under:
Multithreading: more on ManualResetEvent
Tue, May 19 2009 18:25

[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! :) )

Windows API Code Pack for .NET
Tue, May 19 2009 12:06

Just noticed this package that should be useful for all .NET developers that want to use the new Windows 7 features.

by luisabreu | with no comments
Filed under: ,
Multithreading: ManualResetEvent events
Tue, May 19 2009 10:17

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.

by luisabreu | with no comments
Filed under: ,
More Posts Next page »

Search

This Blog

Tags

Community

Archives

Syndication

Email Notifications

News




  • View Luis Abreu's profile on LinkedIn


    Follow me at Twitter

    My books

    Silverlight 4.0: Curso Completo

    ASP.NET 4.0: Curso Completo

    Portuguese LINQ book cover

    Portuguese ASP.NET 3.5 book cover

    Portuguese ASP.NET AJAX book cover

    Portuguese ASP.NET AJAX book cover