Home > Software engineering >  why does Rc works in async fn
why does Rc works in async fn

Time:11-20

I found this example compile successfully, but isn't Rc<> thread unsafe? What if tikio start multi thread to execute test fn, won't it cause Rc to run on different threads? a newbe to rust, pls help

use std::rc::Rc;
use tokio::join;
use std::time;
use async_std::task::{sleep};



async fn test(t:Rc<String>){
    let k = t;
    println!("1. test,{:?}", k);
    sleep(time::Duration::from_secs(1)).await;
    println!("2. test,{:?}", k);
}


#[tokio::main]
async fn main() {
    let r = Rc::new("abc".to_string());
    let f1 = test(r.clone());
    let f2 = test(r.clone());
    join!(f1,f2);
}


CodePudding user response:

This is a bit nuanced, but #[tokio::main] will rewrite your async main() into something like this:

fn main() {
    tokio::runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap()
        .block_on(async {
            // your code from `async main()`
        })
}

The last step that actually runs everything, .block_on(), does not require the given task to be thread-safe (a.k.a. implement Send) because it will not be ran on a separate thread, even when using the multi-threaded executor:

This runs the given future on the current thread, blocking until it is complete, and yielding its resolved result.

Other tokio utilities and any spawned tasks may be ran on separate threads, and even move between them, but not the initial task.

  • Related