923-thread-pool — Thread Pool
Tutorial
The Problem
Spawning a new OS thread for each task is expensive: thread creation costs ~10-100 microseconds and each thread consumes stack memory. For workloads with many short tasks, the thread creation overhead dominates. A thread pool pre-creates N worker threads and reuses them for many tasks. Work is submitted to a queue; idle workers pick up and execute tasks. This is the foundation of most concurrent runtime systems: Java's Executors, Python's concurrent.futures.ThreadPoolExecutor, .NET's ThreadPool, and Rust's rayon. This example shows the manual implementation.
🎯 Learning Outcomes
Arc<Mutex<Receiver<Task>>> for work stealingBox<dyn FnOnce() + Send> as the type-erased task representationThread module and Domain for work poolsCode Example
#![allow(clippy::all)]
// Placeholder — Thread PoolKey Differences
Box<dyn FnOnce() + Send> is the idiomatic task type; OCaml uses unit -> unit functions with explicit type casting.Receiver in Arc<Mutex> for fair multi-worker distribution; OCaml uses Queue.t + Mutex + Condition explicitly.Drop on the pool gracefully shuts down via channel closure; OCaml requires explicit Thread.join coordination.rayon crate provides a work-stealing thread pool as a library; OCaml's parallel library provides similar functionality.OCaml Approach
OCaml's Thread module: Thread.create f x spawns; Thread.join t waits. A pool: create N threads sharing a Queue.t protected by Mutex. OCaml 5 Domain.spawn enables parallel execution on multi-core. The Thread_pool library on opam provides a production-quality implementation. OCaml's Lwt and Eio runtimes implement work-stealing pools internally for their task schedulers. The main OCaml advantage: green threads in Lwt/Eio are cheaper than OS threads.
Full Source
#![allow(clippy::all)]
// Placeholder — Thread PoolDeep Comparison
923-thread-pool — Language Comparison
std vs tokio
| Aspect | std version | tokio version |
|---|---|---|
| Runtime | OS threads via std::thread | Async tasks on tokio runtime |
| Synchronization | std::sync::Mutex, Condvar | tokio::sync::Mutex, channels |
| Channels | std::sync::mpsc (unbounded) | tokio::sync::mpsc (bounded, async) |
| Blocking | Thread blocks on lock/recv | Task yields, runtime switches tasks |
| Overhead | One OS thread per task | Many tasks per thread (M:N) |
| Best for | CPU-bound, simple concurrency | I/O-bound, high-concurrency servers |
Exercises
submit_with_result<T: Send>(f: impl FnOnce() -> T) -> impl Future<Output=T> method using channels.