Intel® Moderncode for Parallel Architectures
Support for developing parallel programming applications on Intel® Architecture.

Help with C# ThreadPool synchronization

Tudor
New Contributor I
848 Views
Hey there,

When using a ThreadPool, I sometimes find myself needing a way to make the current thread wait for all the ThreadPool threads to finish their work. Since there is no method that waits for all threads to finish, I use an improvised barrier, like so:

- each ThreadPool thread contains the following code upon exit:

[c-sharp]lock (locker)
{
runningThreads--;
Monitor.Pulse(locker);
}
[/c-sharp]


- the calling thread contains the following code:

[c-sharp]lock (locker)
{
while (runningThreads > 0)
{
Monitor.Wait(locker);
}
}
[/c-sharp]


where runningThreads is the total number of threads that are created by the ThreadPool.
This brings along several problems: the extra synchronization decreases performance considerably (it's about 20% slower than using regular threads and waiting for them with joins in a for loop). Also, now I have to count the threads when they start executing code, which requires extra synchronization.
Is there a faster way to accomplish what I have described? I wouldn't want to do a wait-spin on GetAvailableThreads...

Thank you.
0 Kudos
1 Solution
gaston-hillar
Valued Contributor I
848 Views
Quoting - Tudor Serban
Hey there,

When using a ThreadPool, I sometimes find myself needing a way to make the current thread wait for all the ThreadPool threads to finish their work. Since there is no method that waits for all threads to finish, I use an improvised barrier, like so:

- each ThreadPool thread contains the following code upon exit:

[c-sharp]lock (locker)
{
runningThreads--;
Monitor.Pulse(locker);
}
[/c-sharp]


- the calling thread contains the following code:

[c-sharp]lock (locker)
{
while (runningThreads > 0)
{
Monitor.Wait(locker);
}
}
[/c-sharp]


where runningThreads is the total number of threads that are created by the ThreadPool.
This brings along several problems: the extra synchronization decreases performance considerably (it's about 20% slower than using regular threads and waiting for them with joins in a for loop). Also, now I have to count the threads when they start executing code, which requires extra synchronization.
Is there a faster way to accomplish what I have described? I wouldn't want to do a wait-spin on GetAvailableThreads...

Thank you.

Hi Tudor,

You can use event wait handles (WaitHandle).

Event wait handles encapsulate operating system specific objects that wait for exclusive access to shared resources. Using them, it is easier to wait for threads signals to continue working when their jobs were done.
You can create an AutoResetEvent instance for each thread and use the Set() method to signal, then, in the coordination thread, you can use WaitHandle.WaitAll sending the auto reset events to monitor array as a parameter.

You can find code to download with examples using AutoResetEvent for free in http://www.packtpub.com/beginners-guide-for-C-sharp-2008-and-2005-threaded-programming/book , code download link.

However, be careful if you are using Windows Forms, because you have to change from STAThread to MTAThread in order to use WaitHandles.

Are you working with C# 3.0 / VS 2008 or are you planning to use C# 4.0 / VS 2010. You have other alternatives and in C# 4.0 / VS 2010, it is simpler using Tasks.

I hope it helps.

Cheers,

Gastn

View solution in original post

0 Kudos
3 Replies
gaston-hillar
Valued Contributor I
849 Views
Quoting - Tudor Serban
Hey there,

When using a ThreadPool, I sometimes find myself needing a way to make the current thread wait for all the ThreadPool threads to finish their work. Since there is no method that waits for all threads to finish, I use an improvised barrier, like so:

- each ThreadPool thread contains the following code upon exit:

[c-sharp]lock (locker)
{
runningThreads--;
Monitor.Pulse(locker);
}
[/c-sharp]


- the calling thread contains the following code:

[c-sharp]lock (locker)
{
while (runningThreads > 0)
{
Monitor.Wait(locker);
}
}
[/c-sharp]


where runningThreads is the total number of threads that are created by the ThreadPool.
This brings along several problems: the extra synchronization decreases performance considerably (it's about 20% slower than using regular threads and waiting for them with joins in a for loop). Also, now I have to count the threads when they start executing code, which requires extra synchronization.
Is there a faster way to accomplish what I have described? I wouldn't want to do a wait-spin on GetAvailableThreads...

Thank you.

Hi Tudor,

You can use event wait handles (WaitHandle).

Event wait handles encapsulate operating system specific objects that wait for exclusive access to shared resources. Using them, it is easier to wait for threads signals to continue working when their jobs were done.
You can create an AutoResetEvent instance for each thread and use the Set() method to signal, then, in the coordination thread, you can use WaitHandle.WaitAll sending the auto reset events to monitor array as a parameter.

You can find code to download with examples using AutoResetEvent for free in http://www.packtpub.com/beginners-guide-for-C-sharp-2008-and-2005-threaded-programming/book , code download link.

However, be careful if you are using Windows Forms, because you have to change from STAThread to MTAThread in order to use WaitHandles.

Are you working with C# 3.0 / VS 2008 or are you planning to use C# 4.0 / VS 2010. You have other alternatives and in C# 4.0 / VS 2010, it is simpler using Tasks.

I hope it helps.

Cheers,

Gastn
0 Kudos
Tudor
New Contributor I
848 Views
Thanks alot. I really forgot about AutoResetEvents. It is indeed faster than to use that barrier I just described. What's funny is that I used AutoResetEvents for this exact same problem for a college project last year and forgot about it. :)) It's funny how programmers always have this tendency to reinvent the wheel. Unfortunately, it seems the array you can wait on must have at max 64 handles. But for loop WaitOne() is just the same I suppose.

I am using VS 2008 but plan to get 2010 as soon as they have a final release. I've played a bit with the beta of the Task Parallel Library, seen some videos and it looks exciting. Also, the thread debugger seems to be much improved.

Btw, I see that you have written a book on parallel programming in C#. I've been looking for something like this for a while. Any idea what the best way to purchase it from Romania is? Ebay? Amazon?
0 Kudos
gaston-hillar
Valued Contributor I
848 Views
Quoting - Tudor Serban
Thanks alot. I really forgot about AutoResetEvents. It is indeed faster than to use that barrier I just described. What's funny is that I used AutoResetEvents for this exact same problem for a college project last year and forgot about it. :)) It's funny how programmers always have this tendency to reinvent the wheel. Unfortunately, it seems the array you can wait on must have at max 64 handles. But for loop WaitOne() is just the same I suppose.

I am using VS 2008 but plan to get 2010 as soon as they have a final release. I've played a bit with the beta of the Task Parallel Library, seen some videos and it looks exciting. Also, the thread debugger seems to be much improved.

Btw, I see that you have written a book on parallel programming in C#. I've been looking for something like this for a while. Any idea what the best way to purchase it from Romania is? Ebay? Amazon?

Hi Tudor,

With Tasks you'll be able touse Tasks.Waitall . Simpler. However, you'll have to be careful because VS 2010 is still in Beta 1.
The best way to purchase from Romania is directly from the published, Packt Publishing Ltd. because it is cheaper and they do not add shipping costs: www.packtpub.com

My book is focused on giving the first steps on threading with C#.

Then, if you want to dive deeper with algorithms you can read other books. For example, Dr. Clay Breshears, auto-defined as a"thread monkey" has recently published his book "The Art of Concurrency". I haven't had time to read it yet. However, its table of contents is really exciting. It covers very interesting topics. Clay is an expert and you'll probably meet him in these forums.

If you want to read more on the topic, Joe Duffy published an excellent book, "Concurrent Programming on Windows", mixing C++ and C# examples. It is a big book, more than 1,000, but worth reading, too.

Cheers,

Gastn
0 Kudos
Reply