tokio::runtime::Handle でスレッドを跨ぐ
tokio::runtime::Handle を最近まで知らなくて無駄なコードを書いてたのでメモ。
Handle とは意味的には Runtime への参照になっている。
https://docs.rs/tokio/1.7.1/tokio/runtime/struct.Handle.html
Handle のドキュメントにもあるように、これを使うと現在のスレッドの Runtime への参照を取り出して別スレッドで同じ Runtime を使い回すことができる。
#[tokio::main] async fn main() { let handle = tokio::runtime::Handle::current(); std::thread::spawn(move || handle.block_on(run_in_child_thread())) .join() .unwrap(); } async fn run_in_child_thread() { todo!() }
同様に tokio の非同期なコードと rayon のようなスレッドによるデータ並列なコードを組み合わせるのも Handle を使えば簡単にできる。
use rayon::prelude::*; #[tokio::main] async fn main() { let handle = tokio::runtime::Handle::current(); [1, 2, 3].into_par_iter().for_each(|i| { handle.block_on(async { cpu_intensive_func1(i); tokio::time::sleep(tokio::time::Duration::from_secs(i)).await; cpu_intensive_func2(i); println!("Finished {}", i); }); }); }