Rust Tokio Runtime
A Tokio runtime is the Tokio engine that runs tasks. A multi-thread runtime spreads tasks over several worker threads.
Build a multi-thread runtime
The default shape: a pool of worker threads shares all your tasks:
let runtime = Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();Or keep everything on one thread
The current-thread runtime runs every task on the thread that started it โ simple and light:
let runtime = Builder::new_current_thread()
.enable_all()
.build()
.unwrap();block_on runs one future to the end
block_on is the front door. It drives the future until the future finishes. It also drives every task the future spawns. Then it hands back the value:
let answer = runtime.block_on(async { 20 + 22 });
println!("answer = {answer}");Example
// Cargo.toml: tokio = { version = "1", features = ["full"] }
use tokio::runtime::Builder;
fn main() {
let runtime = Builder::new_multi_thread()
.worker_threads(2)
.enable_all()
.build()
.unwrap();
let total = runtime.block_on(async {
let a = tokio::spawn(async { 20 });
let b = tokio::spawn(async { 22 });
a.await.unwrap() + b.await.unwrap()
});
println!("total = {}", total);
}Key points
- Work stealing: an idle worker takes tasks from a busy one, so no thread sits idle
- Call .enable_all() so the timer and I/O drivers are switched on
- A runtime is the worker pool that keeps every task moving.
- The current-thread shape is enough for small tools.
In this example, Builder creates a runtime with exactly two worker threads. enable_all switches on the timer and I/O drivers. block_on hands the runtime one future and waits until it ends. Inside, two tasks run and their results are added together. The runtime shuts down when block_on returns and the runtime value is dropped.
Note
#[tokio::main] is just a shortcut โ it builds a multi-thread runtime and calls block_on for you.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท Rust Playground
Exercise
What does block_on do?