非同期処理
このブログが詳しくてよかった
Rustは組み込みなどでも動くため、(Goのgoroutineのような)非同期処理をいい感じに管理してくれるグリーンスレッド的なものは用意されてない。
async/awaitが実装されて、Futureが実装されたけど それを実行するランタイムは実は用意されてない!
Futureは未来で値が決まるコンテナと、完了したかどうかを返すpollが用意されてるのみである ランタイムは各自クレートでやってもらう。たとえばtokioは非同期処理のランタイムを提供する rustでは、非同期関数の中でブロッキング処理を読んでしまうと、そこでそのスレッドが止まるのでNG.
解決策はまず非同期版の関数を使うこと
他にも明示的にコードで操作する方法がある
たとえば tokio では
spawn_blocking or block_in_place を使うこと
spawn_blocking: で囲ったらその部分は別のブロッキング実行用スレッドに飛ばされて実行する
block_in_place は現在のスレッドをブロッキング処理に使う
Goのgoroutineはsysmonスレッドという監視役がいて、それがsyscall/netpollなどを検出して自動的に他の実行キューに入れてくれるので明示的に書かなくて良い感じになっている
このスライドによると async-std も tokio もgoroutineのように自動的に長時間ブロックしてたら検知して別のスレッドに投げるをやろうとはしたが、全自動まではいかず、tail-latency対策程度にとどまっている。よってやはり明示的に spawn_blocking 等が必要