-
Hi, consider this example code: #[tokio::main(flavor = "current_thread")]
async fn main() {
call_sync();
}
pub fn call_sync() {
let handle = Handle::current();
let five = std::thread::spawn(move || {
handle.block_on(get_five_async())
})
.join()
.unwrap();
println!("{five:?}");
}
pub async fn get_five_async() -> i32 {
sleep(core::time::Duration::from_millis(100)).await;
5
} with a |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 8 replies
-
This fails because the timer driver runs on the main thread, but by calling the blocking To fix this, change use tokio::runtime::Handle;
use tokio::sync::oneshot;
use tokio::time::sleep;
#[tokio::main(flavor = "current_thread")]
async fn main() {
call_sync().await;
}
pub async fn call_sync() {
let (send, recv) = oneshot::channel();
let handle = Handle::current();
std::thread::spawn(move || {
let res = handle.block_on(get_five_async());
let _ = send.send(res);
});
let five = recv.await;
println!("{five:?}");
}
pub async fn get_five_async() -> i32 {
sleep(core::time::Duration::from_millis(100)).await;
5
} You can also use use tokio::runtime::Handle;
use tokio::time::sleep;
#[tokio::main(flavor = "current_thread")]
async fn main() {
call_sync().await;
}
pub async fn call_sync() {
let handle = Handle::current();
let five = tokio::task::spawn_blocking(move || {
handle.block_on(get_five_async())
}).await.unwrap();
println!("{five:?}");
}
pub async fn get_five_async() -> i32 {
sleep(core::time::Duration::from_millis(100)).await;
5
} You can read more about blocking the thread in this article. |
Beta Was this translation helpful? Give feedback.
This fails because the timer driver runs on the main thread, but by calling the blocking
call_sync
method on the main thread, you never yield back to the runtime, and so the timer driver is never able to notify any of its timers that they have completed. Even if you makecall_sync
async, then the same issue will appear because then you are calling the blockingstd::thread::JoinHandle::join
method.To fix this, change
call_sync
to be async, then use an asynchronous way to wait for the thread to complete: