CodeBlanks Logo Icon CodeBlanks

tokio::sync

Learn async synchronization primitives from tokio::sync.

tokio::sync

tokio::sync offers synchronization tools between tasks: Mutex, RwLock (they don't block the thread while waiting for the lock), mpsc, broadcast, watch and oneshot for a one-time reply:

let (tx, rx) = tokio::sync::oneshot::channel();
tokio::spawn(async move {
    tx.send(6 * 7).unwrap();
});
println!("{}", rx.await.unwrap());   // 42

oneshot is ideal for the "give a task some work, get its result in a single message" pattern.

std counterpart: a one-message channel

The standard library has no separate oneshot, but an mpsc channel used for a single message does the same job:

use std::sync::mpsc;
use std::thread;

let (tx, rx) = mpsc::channel();
thread::spawn(move || {
    tx.send(6 * 7).unwrap();
});
println!("{}", rx.recv().unwrap());

recv waits until a message arrives; if the sender is dropped without sending, it returns Err.

Practice One-time reply

Open a channel with mpsc::channel. Let a separate thread send the result of 6 * 7; let the main thread receive it with recv and print it.

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();
    thread::spawn(move || {
        tx.send(6 * 7).unwrap();
    });
    println!("{}", rx.recv().unwrap());
}

Expected output

42

Questions and answers

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

1 When is <code>std::sync::Mutex</code> acceptable in async code?

  • Never
  • Always
  • Only on a single thread
  • When the lock is held briefly and not across an .await Correct answer

Explanation: Holding a std mutex across .await can block and also makes the future non-Send; in that case tokio::sync::Mutex is needed.

2 Wait for the message

Question
let (tx, rx) = mpsc::channel();
thread::spawn(move || tx.send(42).unwrap());
let n = rx.____().unwrap();
Answer
let (tx, rx) = mpsc::channel();
thread::spawn(move || tx.send(42).unwrap());
let n = rx.recv().unwrap();

Explanation: recv waits until a message arrives.

3 Tool and use

Term Meaning
oneshot Single reply
mpsc Many producers, one consumer
broadcast Broadcast to all
watch Watch the latest value

All lessons in Advanced