S h o r t S t o r i e s

// Tales from software development

Waiting on multiple threads

with 2 comments

I’m currently implementing an interface that needs to communicate with several servers each time its methods are called. To reduce the elapsed time required the calls to each server are made concurrently using a thread per server. So what’s the best way to wait for all the threads to complete ?

If you search the internet you’ll probably find code examples based on using a semaphore for each thread. When the thread is started the Semaphore’s count is set to 1 (a non-signalled state) and when the thread completes the count is set to 0 which puts the Semaphore into the signalled state. The Semaphore’s static WaitAll() method is used to wait for all the Semaphores to enter the signalled state.

If you know anything about threading then you’ll probably know that while you can use a semaphore in this way, a ManualResetEvent is a better match for what is required here. Each thread uses a ManualResetEvent which is initialised in its non-signalled state by passing false to its constructor. When the thread completes it puts the ManualResetEvent into the signalled state by calling its Set() method. As in the previous example, the WaitAll() static method of the ManualResetEvent class is used to wait for all the threads to complete.

The problem with both these approaches is that creating lots of WaitHandles (the object that underlies the implementation of Semaphores and ManualResetEvents) has a fairly high overhead. This might not be worth worrying about for a few threads but if you want a scalable solution then using a WaitHandle per thread isn’t a good idea.

Joe Duffy presents an elegant solution to this problem on page 368 of his recently published Concurrent Programming on Windows. The code uses a single ManualResetEvent that is initialised in its non-signalled state and a thread safe count of the number of active threads is maintained using the Interlocked object:

activeThreadCount = 0;
manualResetEvent = new ManualResetEvent(false);
foreach (string server in urls)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += new DoWorkEventHandler(BackgroundWorkerDoWork);
    worker.RunWorkerAsync();
    Interlocked.Increment(ref activeThreadCount);
} 

 
When each thread completes it reduces the active thread count by 1 and if the counter has reached 0 then the ManualResetEvent is signalled by calling its Set() method:

if (Interlocked.Decrement(ref activeThreadCount) == 0)
{
    manualResetEvent.Set();
}

 
Now the code that is waiting for the threads to complete only needs to call the ManualResetEvent’s WaitOne() instance method:

manualResetEvent.WaitOne();
Advertisements

Written by Sea Monkey

June 9, 2009 at 7:00 am

Posted in Deployment

Tagged with

2 Responses

Subscribe to comments with RSS.

  1. […] previous post, Waiting on multiple threads, mentioned Joe Duffy’s approach to synchronising multiple threads using a single WaitHandle. […]

  2. Any possibility to get this in vb.net, thansk in advance!

    l a

    September 1, 2009 at 3:31 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: