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
400
Cancel Safetyとスレッドリーク
garasubo
July 24, 2024
Tweet
Share
More Decks by garasubo
See All by garasubo
RustでISUCONに勝つには
garasubo
1
600
Rustでの自作OSをやってきて
garasubo
0
1k
Armの仮想化支援機構を用いてハイパーバイザーを自作する
garasubo
3
6.9k
RustからX Window Systemを触る
garasubo
0
600
Rustで始める自作組込みOS
garasubo
1
3.4k
クラウド向けOS(?)Unikernelとは何か
garasubo
0
1.7k
論文紹介:KVM/ARM: The Design and Implementation of the Linux ARM Hypervisor
garasubo
0
550
Featured
See All Featured
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
Large-scale JavaScript Application Architecture
addyosmani
510
110k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Java REST API Framework Comparison - PWX 2021
mraible
28
8.3k
Building Better People: How to give real-time feedback that sticks.
wjessup
365
19k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2k
A better future with KSS
kneath
238
17k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
2
290
Code Review Best Practice
trishagee
65
17k
Speed Design
sergeychernyshev
25
670
Fireside Chat
paigeccino
34
3.1k
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コンパイラでも保証しきれない性質がたくさんある • ドキュメントをきちんと読んで非同期プログラミングの仕組みを理解しよう • テスト・監視など他のプログラミング言語でも有用な当たり前のことをしましょう