OPTiM TECH BLOG Meetup 開催!#1「Rustの非同期プログラミングは何を実現するのか」へ参加したのがきっかけで、Rust.Tokyo 2019にもチケットを予約して、Rustの勉強を始めたiOSエンジニアです。
2019年11月リリース予定のRust1.39で遂にawait/asyncが正式対応する話でしたが、いち早く、試したくて、チャレンジした内容を紹介します。
動作確認環境
- MacBook Air
- macOS 10.14.4
Rustをインストール
curl -sSf https://sh.rustup.rs | sh
Rustをインストール済みの場合は読み飛ばしてください。
カレントのRustバージョンを確認する
rustc -V
2019年10月25日時点でrustc 1.38.0 (625451e37 2019-09-23)でした。
Rust 1.39 betaへの切り替え方法
rustup install beta
rustup default beta
rustc -V
2019年10月25日時点でrustc 1.39.0-beta.6 (224f0bc90 2019-10-15)でした。
デフォルトのツールチェインを切り替えずに、ディレクトリ単位で切り替える方法
詳しくはこちらを参照してください。
Rustによる非同期プログラミング(await)を試す
Cargo.toml に runtime を追加します。
[dependencies]
runtime = "0.3.0-alpha.7"
ソースコード
#![allow(non_snake_case)]
use runtime::time::Delay;
use std::{thread, time};
async fn foo1() {
for i in 0..10 {
Delay::new(time::Duration::from_millis(500)).await;
println!("foo1:{} Thread[{:?}]", i, thread::current().id());
}
}
async fn foo2() {
for i in 0..10 {
Delay::new(time::Duration::from_millis(500)).await;
println!("foo2:{} Thread[{:?}]", i, thread::current().id());
}
}
#[runtime::main]
async fn main() {
let handles = &mut [runtime::spawn(foo1()), runtime::spawn(foo2())];
for handle in handles {
handle.await;
}
}
Rustによる非同期プログラミングで紹介されているソースコードを試しました。
https://ttis.croud.jp/?uuid=eafa5e19-1826-4700-9149-e2ad25f06a4e
実行結果
foo2:0 Thread[ThreadId(5)]
foo1:0 Thread[ThreadId(6)]
foo2:1 Thread[ThreadId(7)]
foo1:1 Thread[ThreadId(8)]
foo2:2 Thread[ThreadId(9)]
foo1:2 Thread[ThreadId(4)]
foo1:3 Thread[ThreadId(3)]
foo2:3 Thread[ThreadId(2)]
foo2:4 Thread[ThreadId(6)]
foo1:4 Thread[ThreadId(5)]
foo2:5 Thread[ThreadId(8)]
foo1:5 Thread[ThreadId(7)]
foo1:6 Thread[ThreadId(9)]
foo2:6 Thread[ThreadId(4)]
foo1:7 Thread[ThreadId(3)]
foo2:7 Thread[ThreadId(2)]
foo1:8 Thread[ThreadId(5)]
foo2:8 Thread[ThreadId(6)]
foo1:9 Thread[ThreadId(7)]
foo2:9 Thread[ThreadId(8)]
因みにRust 1.38でビルドするとawaitに対応していないので当然エラーになります。
error[E0658]: async blocks are unstable
--> /Users/sam/.cargo/registry/src/github.com-1ecc6299db9ec823/runtime-raw-0.3.0-alpha.5/src/lib.rs:65:15
|
65 | let fut = async move {
| _______________^
66 | | let t = fut.await;
67 | | let _ = tx.send(t);
68 | | };
| |_____^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/50547
error[E0658]: async/await is unstable
--> /Users/sam/.cargo/registry/src/github.com-1ecc6299db9ec823/runtime-raw-0.3.0-alpha.5/src/lib.rs:66:17
|
66 | let t = fut.await;
| ^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/50547
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.
error: Could not compile `runtime-raw`.
warning: build failed, waiting for other jobs to finish...
error: build failed
安定版Rustに戻す方法
rustup default stable