my test code:
use tokio::task::yield_now;
use std::rc::Rc;
#[tokio::main]
async fn main() {
tokio::spawn(async {
let rc = Rc::new("hello");
println!("{}", rc);
yield_now().await;
});
}
I don’t understand,since a Tokio task runs on only one thread at a time, there won’t be any data races involving the local variable rc across multiple threads. So why does tokio::spawn require a Send bound for local variables?
is compile failed:
Compiling playground v0.0.1 (/playground)
error: future cannot be sent between threads safely
--> src/main.rs:6:5
|
6 | / tokio::spawn(async {
7 | | let rc = Rc::new("hello");
8 | | println!("{}", rc);
... |
11 | | });
| |______^ future created by async block is not `Send`
|
= help: within `{async block@src/main.rs:6:18: 6:23}`, the trait `Send` is not implemented for `Rc<&str>`, which is required by `{async block@src/main.rs:6:18: 6:23}: Send`
note: future is not `Send` as this value is used across an await
--> src/main.rs:10:21
|
7 | let rc = Rc::new("hello");
| -- has type `Rc<&str>` which is not `Send`
...
10 | yield_now().await;
| ^^^^^ await occurs here, with `rc` maybe used later
note: required by a bound in `tokio::spawn`
--> /playground/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/task/spawn.rs:167:21
|
165 | pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
| ----- required by a bound in this function
166 | where
167 | F: Future + Send + 'static,
| ^^^^ required by this bound in `spawn`
error: could not compile `playground` (bin "playground") due to 1 previous error