thumb|400px|A sample thread pool (green boxes) with waiting tasks (blue) and completed tasks (yellow)

In computer programming, a thread pool is a software design pattern for achieving concurrency of execution in a computer program. Often also called a replicated workers or worker-crew model, a thread pool maintains multiple threads waiting for tasks to be allocated for concurrent execution by the supervising program. By maintaining a pool of threads, the model increases performance and avoids latency in execution due to frequent creation and destruction of threads for short-lived tasks. Another good property - the ability to limit system load, when we use fewer threads than available. The number of available threads is tuned to the computing resources available to the program, such as a parallel task queue after completion of execution.

Performance

The size of a thread pool is the number of threads kept in reserve for executing tasks. It is usually a tuneable parameter of the application, adjusted to optimize program performance. In these cases the performance benefits of use may be secondary.

Typically, a thread pool executes on a single computer. However, thread pools are conceptually related to server farms in which a master process, which might be a thread pool itself, distributes tasks to worker processes on different computers, in order to increase the overall throughput. Embarrassingly parallel problems are highly amenable to this approach.

The number of threads may be dynamically adjusted during the lifetime of an application based on the number of waiting tasks. For example, a web server can add threads if numerous web page requests come in and can remove threads when those requests taper down. The cost of having a larger thread pool is increased resource usage. The algorithm used to determine when to create or destroy threads affects the overall performance:

  • Creating too many threads wastes resources and costs time creating the unused threads.
  • Destroying too many threads requires more time later when creating them again.
  • Creating threads too slowly might result in poor client performance (long wait times).
  • Destroying threads too slowly may starve other processes of resources.

In languages

In bash implemented by <code>--max-procs</code> / <code>-P</code> in xargs, for example:

<syntaxhighlight lang="bash">

  1. Fetch 5 URLs in parallel

urls=(

"https://example.com/file1.txt"

"https://example.com/file2.txt"

"https://example.com/file3.txt"

"https://example.com/file4.txt"

"https://example.com/file5.txt"

)

printf '%s\n' "${urls[@]}" | xargs -P 5 -I {} curl -sI {} | grep -i "content-length:"

</syntaxhighlight>

In Go, called worker pool:

<syntaxhighlight lang="go">

package main

import (

"fmt"

"time"

)

func worker(id int, jobs <-chan int, results chan<- int) {

for j := range jobs {

fmt.Println("worker", id, "started job", j)

time.Sleep(time.Second)

fmt.Println("worker", id, "finished job", j)

results <- j * 2

}

}

func main() {

const numJobs = 5

jobs := make(chan int, numJobs)

results := make(chan int, numJobs)

for w := 1; w <= 3; w++ {

go worker(w, jobs, results)

}

for j := 1; j <= numJobs; j++ {

jobs <- j

}

close(jobs)

for a := 1; a <= numJobs; a++ {

<-results

}

}

</syntaxhighlight>

It will print:

<syntaxhighlight lang="console">

$ time go run worker-pools.go

worker 1 started job 1

worker 2 started job 2

worker 3 started job 3

worker 1 finished job 1

worker 1 started job 4

worker 2 finished job 2

worker 2 started job 5

worker 3 finished job 3

worker 1 finished job 4

worker 2 finished job 5

real 0m2.358s

</syntaxhighlight>

See also

  • Asynchrony (computer programming)
  • Object pool pattern
  • Concurrency pattern
  • Grand Central Dispatch
  • Parallel Extensions (.NET)
  • Parallelization
  • Server farm
  • Staged event-driven architecture

References

  • "Query by Slice, Parallel Execute, and Join: A Thread Pool Pattern in Java" by Binildas C. A.
  • "Thread pools and work queues" by Brian Goetz
  • "A Method of Worker Thread Pooling" by Pradeep Kumar Sahu
  • "Work Queue" by Uri Twig: C++ code demonstration of pooled threads executing a work queue.
  • "Windows Thread Pooling and Execution Chaining"
  • "Smart Thread Pool" by Ami Bar
  • "Programming the Thread Pool in the .NET Framework" by David Carmona
  • "Creating a Notifying Blocking Thread Pool in Java" by Amir Kirsh
  • "Practical Threaded Programming with Python: Thread Pools and Queues" by Noah Gift
  • "Optimizing Thread-Pool Strategies for Real-Time CORBA" by Irfan Pyarali, Marina Spivak, Douglas C. Schmidt and Ron Cytron
  • "Deferred cancellation. A behavioral pattern" by Philipp Bachmann
  • "A C++17 Thread Pool for High-Performance Scientific Computing" by Barak Shoshany