How does tokio's multi-thread scheduler behave with futures generated inside a while loop?

⚓ Rust    📅 2026-04-06    👤 surdeus    👁️ 6      

surdeus

I'm working on an application that generally can benefit from using tokio's multi-thread scheduler, but for a few use cases it's important that things happen in a particular sequence e.g. transmitting the bytes of firmware for a remote device in ordered chunks. From practical experience I'm fairly certain the runtime respects the semantics of control flows like while loops even in the context of multiple threads and nested future generation, but I haven't seen any obvious confirmation in the documentation.

Take the following scenario:

use tokio;

#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut i = 0u8;
    while i < 25 {
        i = inc(i).await?;
        i = inc(i).await?;
        i = dec(i).await?;
    }
    Ok(())
}

async fn inc(i: u8) -> Result<u8, Box<dyn std::error::Error>> {
    println!("i is going to be increased to {}", i+1);
    Ok(i+1)
}

async fn dec(i: u8) -> Result<u8, Box<dyn std::error::Error>> {
    println!("i is going to be decreased to {}", i-1);
    Ok(i-1)
}

Is the order of operations guaranteed to be inc(), inc(), dec() as written even though each await produces a future and the multi-thread scheduler executes futures on a thread pool, using a work-stealing strategy? I know a given task will be paused at each await in sequence, but could the multi-threaded runtime advance to another loop iteration somehow and produce unpredictable results in the absence of explicit mutex locks?

Part of my confusion stems from a poor understanding of the relationships between tokio tasks and futures -- I think I understand generally how a tokio task relates to a single future it is given when spawned (hosts it/runs it), but my understanding falls apart a little once we bring nested futures (and nested tasks?) generated by the task's root future into the equation in a multi-threaded context.

2 posts - 2 participants

Read full topic

🏷️ Rust_feed