la guarida de DuckMaestro

Thread Pools

So you've decided you want to multithread something? Well, the first question you should ask yourself is (after reading this article of course!) -- "should I use the thread pool?". Here are some basics on what a thread pool is and why you should (or shouldn't) use one.

Thread Pool

  1. Manages a pool of already allocated, reusable threads, available for your evil bidding.
  2. Maintains a queue of tasks, or a to-do list if you will. This list holds on to whatever tasks give the thread pool.
  3. As long as there are tasks to do, the pool keeps its threads busy doing those tasks. Once a thread finishes a task, it moves on to a new task if there is one.
  4. Minimizes the cost associated with creating/destroy threads, because threads are reused instead of created/destroyed.
  5. Minimizes system resource usage by limiting the number of threads it will ask the operating system or virtual machine for.

When to Use a Thread Pool

  1. If you're concerned about your main thread being held up for too long on less-than-important pieces of logic, then you should consider off-loading some of your algorthm to the thread pool.
  2. Thread pools are meant for tasks that will completely relatively quickly. Imagine a line of people and your task is a person -- if you are holding up the line, you are preventing everyone else from doing what they need to do too. Though this is what you wanted to avoid in the first place with regard to your main thread, if too many threads are taking too much time it begins to defeat the purpose of the thread pool, as well as rob other, possibly more important, tasks in the queue of timely completion.
  3. You have tasks that can be broken down into isolated chunks of work with no or relatively simple interdependencies.

When not to Use a Thread Pool

  1. If you're writing high-performance code and are multithreading to that end, requiring fine-grained control over your threads.
  2. If your tasks are highly interdependent and require complex signaling or cross-thread communication.
  3. If your tasks need to complete in a semi-predictable order.
  4. If you need to ensure a thread is on standby so-to-speak, ready at any moment for a particular task.

Other Things to Keep in Mind

  1. Many if not all of the possible trouble-makers when writing multithreaded code also apply to thread pools. Stay mindful.
  2. Because threads are reused from task to task, thread-specific data or state may carry over from the last task to the next task. For example the next task may find unexpected data in variables marked for thread-local storage.
  3. Don't take the attitude of, it's in a separate thread now so I don't need to care about unhandled exceptions. Wrong! The thread is still a thread. Some APIs/runtimes will raise an error for the whole process if a thread has an unhandled exception.

A Quick C#/.NET Example

ThreadPool.QueueUserWorkItem(
    new WaitCallback(
        delegate(object state)
        {
            // do something asynchronously
        }
    )
);

C# is great in this instance because we can use an anonmyous method (and the closure it creates for us) to very easily off-load a subtask to the thread pool. Very painless!

Lastly...

Not all thread pools are created equal. Check the documention on the thread pool or API you are working with to get a better idea of it's features and limitations!

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License except where otherwise noted.


comments powered by Disqus