Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Cancel Safetyとスレッドリーク
Search
garasubo
July 24, 2024
1
570
Cancel Safetyとスレッドリーク
garasubo
July 24, 2024
Tweet
Share
More Decks by garasubo
See All by garasubo
RustでISUCONに勝つには
garasubo
1
720
Rustでの自作OSをやってきて
garasubo
0
1.1k
Armの仮想化支援機構を用いてハイパーバイザーを自作する
garasubo
3
7.2k
RustからX Window Systemを触る
garasubo
0
640
Rustで始める自作組込みOS
garasubo
1
3.5k
クラウド向けOS(?)Unikernelとは何か
garasubo
0
1.8k
論文紹介:KVM/ARM: The Design and Implementation of the Linux ARM Hypervisor
garasubo
0
630
Featured
See All Featured
The Cost Of JavaScript in 2023
addyosmani
53
8.9k
The Pragmatic Product Professional
lauravandoore
36
6.9k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.7k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
920
Docker and Python
trallard
45
3.6k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.9k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.7k
Imperfection Machines: The Place of Print at Facebook
scottboms
268
13k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.4k
Rails Girls Zürich Keynote
gr2m
95
14k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
The World Runs on Bad Software
bkeepers
PRO
70
11k
Transcript
Cancel Safetyと スレッドリーク Rustでも怖い非同期プログラミング
自己紹介 • ハンドルネーム:ガラスボー(@garasubo) • 現在はIdein株式会社に所属 – IoTプラットフォームの開発を担当 – RustをサーバーサイドやIoT端末上で利用 –
エンジニア以外も積極採用中なので興味があれば採用ページを
Cancel Safetyとスレッドリーク • Rustでの非同期プログラミングのおさらい • tokio::selectとcancel safety • プロダクションで起きたスレッドリーク事件
Rustでの非同期プログラミング
Rustでの非同期プログラミング async/.await構文登場以前だと非同期処理の扱いは デファクトがなくライブラリも乱立状態 async/.await構文登場以降はtokioをランタイムとして利用した async/.awaitを使った非同期プログラミングが主流に
tokioとは • Rustの汎用非同期ランタイム • async/.await構文を利用するには何かしらの非同期ランタイムが必要 – スレッド管理やスケジューリングの仕方をカスタマイズできるようにするため – Rustのstd側での提供はなく、よく使われるのがtokio –
詳しい仕組みはAsync Programming in Rustなどを参照 • 多くの非同期処理が絡むライブラリもtokioに依存している場合が多い
tokio::selectと cancel safety
tokio::select • 複数のasync関数を同時に実行して先に終了した方の結果を返すマクロ • 選ばれなかった方のfutureはcancelされて結果が破棄される 選ばれなかった場合のことを考えて、途中で終了しても困らないような関数の みを呼び出す必要がある
tokio::select
Cancel Safety 途中で終了してもデータが欠損したりせず困らないという性質 Cancel Safeでない例: tokio::io::AsyncReadExt::read_exact • 指定されたバッファの長さを全部埋めるまでデータを読み込む • キャンセルされるとバッファにある程度データを取り込んだ状態になるため、途中まで
取り込んだデータが失われてしまう tokioの関数であればcancel safeなものはcancel safeだと書いてあるので ドキュメントを読みましょう
Cancel Safeの見極め方 asyncな関数はawaitが呼び出される箇所でのみ中断される可能性がある async中のあらゆるawaitポイントで実行が止まっても内部状態が失われないこと この性質は型としては表現されないのでコンパイルエラーにはならない
プロダクションで起きた スレッドリーク事件
スレッドリーク事件 右のようなコードを書いたところスレッドが 無限に生成されてプログラムがスタックした
スレッドリーク事件 tokio::selectが呼び出され、 waitとwait2のうちどちらかを待つ wait2が先に終わるとループが続 行し、再びtokio::selectでwait とwait2のどちらかを待つ
スレッドリーク事件 waitは通常だと終了しない処理 (今回は無限ループでスリープ) wait2は比較的短い処理なので通 常ならばwait2の方が先に終了する
スレッドリーク事件 wait2が終わる task内のループが再び実行 waitが呼び出されスレッドが 作られる wait2が終わり再びループへ
スレッドリーク事件 よく見ると無限ループ内にawaitがない つまりcancelしたくてもそもそも中断が できない状態 呼び出されるたびに 中断できないスレッドが溜まっていく
教訓 • 非同期プログラミングではRustコンパイラでも保証しきれない性質がたくさんある • ドキュメントをきちんと読んで非同期プログラミングの仕組みを理解しよう • テスト・監視など他のプログラミング言語でも有用な当たり前のことをしましょう