Thread pool task manager overview

Thread pool task manager classes

The thread pool task manager consists of multiple worker threads that process work items from prioritized queues as shown in the following class diagram:

mtf-runtime-taskman-classes.png

When the task manager is initialized, it determines the number of hardware threads (CPU cores or hyperthreads, if applicable) using Environment.ProcessorCount and creates two threads for each:
  • Processing Thread - the default thread for processing non-blocking work items
  • GUI Thread - the thread for processing work items that can block on the GUI (e.g. through Form.Invoke())

(Note: Work items that can block on the GUI must be scheduled on separate threads to avoid the possibility of a deadlock occurring where a worker is blocked in an Invoke that will never be serviced because the GUI is blocked on that worker)

The prioritized work queue

Each worker thread has a prioritized work queue. The priority queue is a set of queues that are assigned priority values from zero to maximum. Work items are always retrieved from the highest priority queue that contains an item such that higher priority work items are executed prior to lower priority work items.

The work queue is protected by a lock and a semaphore. The lock must be taken when enqueuing or dequeueing work to prevent concurrent access. To minimize contention between competing threads the lock is taken very briefly, just to enqueue or dequeue an item. The semaphore is used to block worker threads that run out of work items.

A fast lock implementation is used that avoids expensive OS synchronization objects such as mutexes where the lock is not contended, which is most commonly the case. For more information on the fast lock implementation, see Spin lock: overview.

Task stealing

The ThreadWorker implementation employs task stealing in the event that a worker runs out of work items. This enables a worker to steal items from the queue of another worker so that it is not possible for a single worker to end up processing a backlog of items while others are sitting idle.

Last edited Aug 30, 2012 at 9:06 AM by jaorme, version 6

Comments

No comments yet.