A thread pool is a collection of worker threads that efficiently execute asynchronous callbacks on behalf of the application. The thread pool is primarily used to reduce the number of application threads and provide management of the worker threads. Applications can queue work items, associate work with waitable treats, automatically queue based on a timer, and tie with I/O.
Thread Pool Architecture
The following applications can benefit from using a thread pool:
- An application that is very parallel and can dispatch a large number of petite work items asynchronously (such spil distributed index search or network I/O).
- An application that creates and demolishes a large number of threads that each run for a brief time. Using the thread pool can reduce the complexity of thread management and the overhead involved ter thread creation and destruction.
- An application that processes independent work items te the background and te parallel (such spil loading numerous tabs).
- An application that voorwaarde perform an off the hook wait on kernel objects or block on incoming events on an object. Using the thread pool can reduce the complexity of thread management and increase spectacle by reducing the number of setting switches.
- An application that creates custom-built waiter threads to wait on events.
The original thread pool has bot downright rearchitected ter Windows Vista. The fresh thread pool is improved because it provides a single worker thread type (supports both I/O and non-I/O), does not use a timer thread, provides a single timer queue, and provides a dedicated persistent thread. It also provides clean-up groups, higher vertoning, numerous pools vanaf process that are scheduled independently, and a fresh thread pool API.
The thread pool architecture consists of the following:
- Worker threads that execute the callback functions
- Waiter threads that wait on numerous wait treats
- A work queue
- A default thread pool for each process
- A worker factory that manages the worker threads
The fresh thread pool API provides more plasticity and control than the original thread pool API. However, there are a few subtle but significant differences. Ter the original API, the wait reset wasgoed automatic, te the fresh API, the wait voorwaarde be explicitly reset each time. The original API treated impersonation automatically, transferring the security setting of the calling process to the thread. With the fresh API, the application voorwaarde explicitly set the security setting.
The following are best practices when using a thread pool:
- The threads of a process share the thread pool. A single worker thread can execute numerous callback functions, one at a time. Thesis worker threads are managed by the thread pool. Therefore, do not terminate a thread from the thread pool by calling TerminateThread on the thread or by calling ExitThread from a callback function.
- An I/O request can run on any thread ter the thread pool. Canceling I/O on a thread pool thread requires synchronization because the cancel function might run on a different thread than the one that is treating the I/O request, which can result ter cancellation of an unknown operation. To avoid this, always provide the OVERLAPPED structure with which an I/O request wasgoed initiated when calling CancelIoEx for asynchronous I/O, or use your own synchronization to ensure that no other I/O can be began on the target thread before calling either the CancelSynchronousIo or CancelIoEx function.
- Clean up all resources created ter the callback function before returning from the function. Thesis include TLS, security contexts, thread priority, and COM registration. Callback functions vereiste also restore the thread state before returning.
- Keep wait treats and their associated objects alive until the thread pool has signaled that it is finished with the treat.
- Mark all threads that are waiting on lengthy operations (such spil I/O flushes or resource cleanup) so that the thread pool can allocate fresh threads instead of waiting for this one.
- Before unloading a DLL that uses the thread pool, cancel all work items, I/O, wait operations, and timers, and wait for executing callbacks to accomplish.
- Avoid deadlocks by eliminating dependencies inbetween work items and inbetween callbacks, by ensuring a callback is not waiting for itself to finish, and by preserving the thread priority.
- Do not queue too many items too quickly te a process with other components using the default thread pool. There is one default thread pool vanaf process, including Svchost.exe. By default, each thread pool has a maximum of 500 worker threads. The thread pool attempts to create more worker threads when the number of worker threads ter the ready/running state vereiste be less than the number of processors.
- Avoid the COM single-threaded apartment specimen, spil it is incompatible with the thread pool. STA creates thread state which can affect the next work voorwerp for the thread. STA is generally long-lived and has thread affinity, which is the opposite of the thread pool.
- Create a fresh thread pool to control thread priority and isolation, create custom-built characteristics, and possibly improve responsiveness. However, extra thread pools require more system resources (threads, kernel memory). Too many pools increases the potential for CPU contention.
- If possible, use a waitable object instead of an APC-based mechanism to signal a thread pool thread. APCs do not work spil well with thread pool threads spil other signaling mechanisms because the system controls the lifetime of thread pool threads, so it is possible for a thread to be terminated before the notification is delivered.
- Use the thread pool debugger extension, !tp. This directive has the following usage:
- pool addressflags
- obj addressflags
- tqueue addressflags
- waiter address
- worker address
For pool, waiter, and worker, if the address is zero, the directive dumps all objects. For waiter and worker, omitting the address dumps the current thread. The following flags are defined: 0x1 (single-line output), 0x2 (dump members), and 0x4 (dump pool work queue).