Thread Pool

Posted by Hugh Ang at 10/31/2007 05:14:00 PM

I mentioned in my last post that I would cover some interesting topics that all relate to thread. Now here is the second one, on thread pool.

Thread pool is an efficient way to achieve concurrency since it saves the cost of creating new threads all the time by reusing threads in a pool. To get a good understanding of how to leverage ThreadPool class in the .NET framework, you can start by reading Jeffery Richter's good article on MSDN. However that was .NET 1.1. In .NET 2.0, the ThreadPool class supports a total of 4 types of uses as opposed to 3, which can be seen clearly from the enumeration in SSCLI2:

enum ThreadpoolThreadType







With the new ThreadPool class, we can

  • 1) call a method on a worker thread by QueueUserWorkItem

  • 2) call a method on an IO Completion port thread by UnsafeQueueNativeOverlapped

  • 3) call a method on an IO Completion port thread when a kernel object is signaled by RegisterWaitForSingleObject

  • 4) call a method on a worker thread by using System.Threading.Timer - note this is the API seemingly irrelevant to ThreadPool

While IO Completion Port (IOCP) is not new to native Windows, the inclusion of its API in thread pool is the latest feature added to .NET 2.0. IOCP is a mechanism on Windows to allow asynchronous IO. The IOCP threads will be woken up and start code execution if IO operation is complete. The Win32 API for this is GetQueuedCompletionStatus, which essentially doesn't return (thread back to the pool) until IO operation is done. And more interestingly, IOCP isn't just limited to being used for IO - ThreadPool.UnsafeQueueNativeOverlapped can be used just like ThreadPool.QueueUserWorkItem. Here is a code snippet for queueing a delegate to the IOCP threads via Overlapped data structure:



    Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, null);

    NativeOverlapped* pOverlapped = overlapped.Pack(IocpThreadProc, null);



Note that unsafe keyword is used as native pointer is created. And here is the delegate:

unsafe static void IocpThreadProc(uint x, uint y, NativeOverlapped* p)











Note that Free must be called in the finally block to ensure that memory is not leaked.

The philosophy of IOCP is that the optimal number of concurrent running threads should be equal to the number of processors, because anything more would introduce the overhead of context switches between different threads. Peeking into the win32threadpool.cpp file of SSCLI2, one can find that while both the number of worker threads and the number of IOCP threads can grow under the ceiling of upper limits set by ThreadPool.SetMaxThreads, IOCP has constraints from CPU utilization also. In other words, even if you set the max of IOCP threads to a number much higher than the number of processros, there won't be more concurrent threads than the number of processors if there is very high CPU utilization. On the other hand, the number of worker threads, under the situation of high CPU utilitzation, will likely grow under the ceiling with requests queued up. This blog has shown empirical results proving this. The example is a bit of extreme in that a large number of highly computation-intensive requests are being queued to the thread pool. However it shouldn't be viewed that IOCP is always the better one to use. Remember now you can still call ThreadPool.SetMaxThreads to throttle the number of concurrent worker threads to achieve good results too. Measuring and tuning would be required in real world situations. While it's great that we have an additional option to be able to queue any requests to IOCP through UnsafeQueueNativeOverlapped, keep in mind that IOCP was designed to be a great mechanism to handle IO asynchronously. Examples, such as System.IO.FileStream, System.Net.Sockets.Socket, System.ServiceModel.Channels.MsmqQueue, etc. can be found in the FCL. So I'd conjecture that while using a custom IO device, if asynchronous IO is desired, the same pattern can be followed by passing the handle of the IO object to ThreadPool.BindHandle to associate the IO device to the IOCP of the ThreadPool.

As to using System.Threading.Timer, this great MSDN Article discusses it pretty well in comparison with System.Timers.Timer and System.Windows.Forms.Timer. It's important to remember that System.Timers.Timer is a wrapper of System.Threading.Timer. System.Windows.Forms.Timer uses a completely different mechanism, which is SetTimer Win32 API, posting WM_TIMER message to the application queue. This means that your delegate added to the Tick event will be running on the same UI thread that created the main application windows forms. As the UI thread processes a lot of messages, including mouse and keyboard messages, this mechanism will surely not get you a lot of mileage for concurrency if that's what you're looking for.

As server apps like ASP.NET, WCF already have concurrency built in, ThreadPool should not be overly used in there. ThreadPool can be ideal in UI applications, Windows service, and batch applications, etc, if they need a lot of concurrency.


Anonymous said...

cialis professional
This then allows the user to achieve the wanted erection, and gets them back on track living a healthy love life.
[url=]generic tadalafil[/url]
As horrible as this sounds there is a ray of light that shines through, and if you find yourself struggling with erectile dysfunction(male impotence) you should know there is hope. - cialis price
You should also note that a prolonged erection (of four hours or more) is potentially damaging to the penis, and you should also seek advice if the erection becomes painful.

Anonymous said...

фильмы dvd фильмы сериалы диски blu-ray магазин
[url=][/url] или [url=][/url]

последние новинки
Идеальный побег / A Perfect Getaway / 2009
Трансформеры: Месть падших / Transformers: Revenge of the Fallen / 2009
Джонни Д / Public Enemies / 2009
Монстри проти чужих / Монстры против пришельцев / Monsters vs Aliens / 2009
Стэн Хельсинг / Stan Helsing / 2009
О, счастливчик! / 2009
Нянька по вызову / The Rebound / 2009
Король Гийом / King Guillaume / 2009
Запрещенная реальность / 2009
Повелители теней / The Telling / 2009
Кража в музее / The Maiden Heist / 2009
Продавец / The Goods: Live Hard, Sell Hard / 2009
2012: Супернова / 2012: Supernova / 2009
Мой ангел-хранитель / My Sister s Keeper / 2009
Причина основания Китая / Jian guo da ye / 2009
Проклятые воды / Midnight Bayou / 2009
Ласковый май / 2009
Затащи меня в Ад / Drag Me to Hell / 2009
Чудаки / Lascars / 2009
Прошивка / Hardwired / 2009
Парк культуры и отдыха / Adventureland / 2009
Крик совы / The Cry of the Owl / 2009
Побег из ГУЛАГа / So weit die Fuesse tragen (As Far As My Feet Will Carry Me) / 2001
Дорогуша / Cheri / 2009
Крыша / 2009
Суррогаты / Surrogates / 2009
Гарри Поттер и Принц-полукровка / Harry Potter and the Half-Blood Prince / 2009
Поворот не туда 3 / Wrong Turn 3: Left for Dead [UNRATED] / 2009
Луна 2112 / Moon / 2009
Последний день будущего / Evilution / 2008
Опасные пассажиры поезда 123 / The Taking of Pelham 123
Предложение / The Proposal / 2009
Бросок кобры / G.I. Joe: The Rise of Cobra / 2009
Миссия Дарвина / G-Force / 2009
Каникулы строгого режима / 2009
Бабник / Spread / 2009
Интимные подробности холостяцкой жизни / Cruising Bar 2 / 2008
Невеста любой ценой / 2009
Дитя тьмы / Orphan / 2009
Девять / 9 / 2009
Представь себе / Imagine That / 2009
Звездный путь / Star Trek / 2009
Район №9 / District 9 / 2009

Anonymous said...

cheap levitra online
These drugs are easily available at your local drugs stores and you can even buy it online.
[url=]generic vardenafil[/url]
Order Levitra (Vardenafil) online without a prescription. - cheap levitra
FDA approved Levitra is no doubt the most effective ED medication ever produced.