Rust
Summary - Tokio
Race two async tasks by combining spawn and select!.
Tokio summary
Tokio provides a runtime for async Rust: the #[tokio::main] entry, light tasks with tokio::spawn, communication between tasks with tokio::sync (mpsc, oneshot, Mutex), async I/O with tokio::fs/net, and racing and cancellation with select!/timeout. Golden rule: don't make blocking calls in an async task; use spawn_blocking if you must.
The worker pattern
A copy of the sender is given to each worker; once the original sender is dropped, the receiver's iterator ends when all workers finish:
let (tx, rx) = mpsc::channel();
for id in 0..4 {
let tx = tx.clone();
thread::spawn(move || tx.send(id * 10).unwrap());
}
drop(tx); // drop the original sender
let sonuclar: Vec<i32> = rx.iter().collect(); // 4 results, order undefined
Since the order of results is undefined, only order-independent summaries (sum, count) can be printed safely.
Exercise Collect from workers
Start four worker threads; let each send id * 10 to the same channel. Drop the original sender, collect the results with rx.iter() and print them as N sonuç, toplam X.
Show example solution
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
for id in 0..4 {
let tx = tx.clone();
thread::spawn(move || tx.send(id * 10).unwrap());
}
drop(tx);
let sonuclar: Vec<i32> = rx.iter().collect();
let toplam: i32 = sonuclar.iter().sum();
println!("{} sonuç, toplam {}", sonuclar.len(), toplam);
}
Test yourself
-
Which pattern fits gathering the results of many workers in one place?
- A cloned sender for each worker (tx.clone()), a single receiver
- A separate global for each worker
- Each worker writes to a file
- It isn't possible
Show answer
A cloned sender for each worker (tx.clone()), a single receiver — mpsc: many producers, single consumer. Once all senders are dropped, the receiver's loop ends by itself.
-
Drop the original sender
for id in 0..4 {
let tx = tx.clone();
thread::spawn(move || tx.send(id).unwrap());
}
____(tx);
let hepsi: Vec<i32> = rx.iter().collect();
Show answer
for id in 0..4 {
let tx = tx.clone();
thread::spawn(move || tx.send(id).unwrap());
}
drop(tx);
let hepsi: Vec<i32> = rx.iter().collect();
-
Group summary
- #[tokio::main]
- Runtime entry
- tokio::spawn
- Task
- select!
- First to finish wins
- spawn_blocking
- Blocking work
Next lesson: thread::spawn