CodeBlanks Logo Icon CodeBlanks

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.

Practice 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.

Starter code

main.rs
use std::sync::mpsc;
use std::thread;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
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);
}

Expected output

4 sonuç, toplam 60

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Which pattern fits gathering the results of many workers in one place?

  • A cloned sender for each worker (tx.clone()), a single receiver Correct answer
  • A separate global for each worker
  • Each worker writes to a file
  • It isn't possible

Explanation: mpsc: many producers, single consumer. Once all senders are dropped, the receiver's loop ends by itself.

2 Drop the original sender

Question
for id in 0..4 {
    let tx = tx.clone();
    thread::spawn(move || tx.send(id).unwrap());
}
____(tx);
let hepsi: Vec<i32> = rx.iter().collect();
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();

Explanation: If the original tx isn't dropped, rx.iter() never ends.

3 Group summary

Term Meaning
#[tokio::main] Runtime entry
tokio::spawn Task
select! First to finish wins
spawn_blocking Blocking work

All lessons in Advanced