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
シェルスクリプトで学ぶ排他制御
Search
Satoru Takeuchi
PRO
September 19, 2020
Technology
0
660
シェルスクリプトで学ぶ排他制御
以下動画のテキストです。
https://youtu.be/RPKt1p2SkxY
Satoru Takeuchi
PRO
September 19, 2020
Tweet
Share
More Decks by Satoru Takeuchi
See All by Satoru Takeuchi
eBPF
sat
PRO
1
97
waruiBPF
sat
PRO
0
94
eBPFとwaruiBPF
sat
PRO
4
3.1k
Pythonのコードの気になる行でスタックトレースを出す
sat
PRO
0
89
ソースコードを読むときの思考プロセスの例 ~markdownのレンダリング方法を知りたかった2 markdownパッケージ~
sat
PRO
0
180
様々なファイルシステム
sat
PRO
0
330
ソースを読む時の思考プロセスの例-MkDocs
sat
PRO
1
420
ソースを読むプロセスの例
sat
PRO
22
18k
メモリマップトファイル
sat
PRO
1
170
Other Decks in Technology
See All in Technology
Cloud WAN MCP Serverから考える新しいネットワーク運用 / 20251228 Masaki Okuda
shift_evolve
PRO
0
100
半年で、AIゼロ知識から AI中心開発組織の変革担当に至るまで
rfdnxbro
0
150
20251218_AIを活用した開発生産性向上の全社的な取り組みの進め方について / How to proceed with company-wide initiatives to improve development productivity using AI
yayoi_dd
0
720
SQLだけでマイグレーションしたい!
makki_d
0
1.2k
2025-12-27 Claude CodeでPRレビュー対応を効率化する@機械学習社会実装勉強会第54回
nakamasato
4
1.1k
マイクロサービスへの5年間 ぶっちゃけ何をしてどうなったか
joker1007
21
8.3k
Introduce marp-ai-slide-generator
itarutomy
0
130
2025-12-18_AI駆動開発推進プロジェクト運営について / AIDD-Promotion project management
yayoi_dd
0
160
NIKKEI Tech Talk #41: セキュア・バイ・デザインからクラウド管理を考える
sekido
PRO
0
220
「もしもデータ基盤開発で『強くてニューゲーム』ができたなら今の僕はどんなデータ基盤を作っただろう」
aeonpeople
0
250
AI駆動開発ライフサイクル(AI-DLC)の始め方
ryansbcho79
0
200
日本Rubyの会: これまでとこれから
snoozer05
PRO
6
250
Featured
See All Featured
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Paper Plane (Part 1)
katiecoart
PRO
0
2.1k
ラッコキーワード サービス紹介資料
rakko
0
1.8M
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
240
Navigating Team Friction
lara
191
16k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
73
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
0
130
Visualization
eitanlees
150
16k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
33
Automating Front-end Workflow
addyosmani
1371
200k
Writing Fast Ruby
sferik
630
62k
The Invisible Side of Design
smashingmag
302
51k
Transcript
シェルスクリプトで学ぶ排他制御 Sep 19th, 2020 Satoru Takeuchi Twitter: satoru_takeuchi, EnSatoru 1
排他制御 • 以下のことを一つの処理からしか操作できないようにする ◦ コード上のある箇所 (クリティカルセクション )の実行 ◦ あるリソースを操作する •
抽象的で意味わからん! ◦ これ聞くだけで「なるほど!」ってなる人はあんまりいない • 実例を使って説明 ◦ 多くの人から見て身近なシェルスクリプトを使う 2
身近な排他制御の使用例 • apt系コマンドが以下のようなメッセージと共に異常終了 • この問題の発生ロジック ◦ apt系コマンドは同時に複数実行できないようになっている ◦ /var/lib/apt/lists/lockが存在しなければ実行、存在すれば異常終了する ▪
上記のようなファイルをロックファイルと呼ぶ ◦ 実際に発生するのはほとんど次のような場合 1. apt系コマンド実行中にC-cで異常終了させたりするとファイルが残る 2. 次に実行すると必ず失敗 3. ユーザがファイルを消せば再実行可能になる 3 E: Could not get lock /var/lib/apt/lists/lock – open (11: Resource temporarily unavailable)
身近な排他制御の使用例 • apt系コマンドが以下のようなメッセージと共に異常終了 • この問題の発生ロジック ◦ apt系コマンドは同時に複数実行できないようになっている ◦ /var/lib/apt/lists/lockが存在しなければ実行、存在すれば異常終了する ▪
上記のようなファイルをロックファイルと呼ぶ ◦ 実際に発生するのはほとんど次のような場合 1. apt系コマンド実行中にC-cで異常終了させたりするとファイルが残る 2. 次に実行すると必ず失敗 3. ユーザがファイルを消せば再実行可能になる 4 E: Could not get lock /var/lib/apt/lists/lock – open (11: Resource temporarily unavailable) 今回のテーマ
最初に思いつく実装: シェルスクリプトで表現 5 if [ -e /var/lib/apt/lists/lock ] ; then
echo <さっきのメッセージ> >&2 exit 1 fi touch /var/lib/apt/lists/lock aptの実処理 rm -f /var/lib/apt/lists/lock ここがクリティカルセクション ①最初にファイルの存在確認 ②なければファイルを作って 他の処理が割り込めないように してから先に進む ③最後にファイルを消して、他のプロセスが実処理を実行できるようにする
これはうまく動かない • 例: apt Aとapt Bを同時に実行 6 if [ -e
/var/lib/apt/lists/lock ] ; then echo <さっきのメッセージ> >&2 exit 1 fi touch /var/lib/apt/lists/lock aptの実処理 rm -f /var/lib/apt/lists/lock if [ -e /var/lib/apt/lists/lock ] ; then echo <さっきのメッセージ> >&2 exit 1 fi touch /var/lib/apt/lists/lock aptの実処理 rm -f /var/lib/apt/lists/lock apt A apt B
これはうまく動かない • 2つのif文が同時に実行。両方ファイルが存在しないと判定する 7 if [ -e /var/lib/apt/lists/lock ] ;
then echo <さっきのメッセージ> >&2 exit 1 fi touch /var/lib/apt/lists/lock aptの実処理 rm -f /var/lib/apt/lists/lock if [ -e /var/lib/apt/lists/lock ] ; then echo <さっきのメッセージ> >&2 exit 1 fi touch /var/lib/apt/lists/lock aptの実処理 rm -f /var/lib/apt/lists/lock apt A apt B ファイルは無いな… ファイルは無いな…
これはうまく動かない • 2つとも先に進んでaptの実処理を実行 ◦ aptの処理が正しく動作しない &データベースがブッ壊れる 8 if [ -e
/var/lib/apt/lists/lock ] ; then echo <さっきのメッセージ> >&2 exit 1 fi touch /var/lib/apt/lists/lock aptの実処理 rm -f /var/lib/apt/lists/lock if [ -e /var/lib/apt/lists/lock ] ; then echo <さっきのメッセージ> >&2 exit 1 fi touch /var/lib/apt/lists/lock aptの実処理 rm -f /var/lib/apt/lists/lock apt A apt B 先に進もう 先に進もう
もうちょっとわかりやすい例 • いわゆるカウンタプログラムを使う ◦ countファイルの初期値は 0 ◦ 一回実行するごとにファイルの中身の数値を 1つ足す ◦
すでに同じプログラムが実行中ならすぐリトライ (スピンロック) • 最初に思いつく実装: inc-counter.sh 9 while : ; do if [ ! -e lock ] ; then break fi done touch lock TMP=$(cat count) echo $((TMP + 1)) >count rm -f lock ここがクリティカルセクション
inc-counterプログラムの並列実行 • カウントを1000増加させるスクリプト(inc-counter-1000.sh)を同時に2つ実行 • 結果 ◦ 期待: 最終的にcountの値が2000になる ◦ 実際:
2000より小さな値になる(ことがある) ▪ 同じCPU上で実行すると起きやすい 10 for ((i=0;i<1000;i++)) ; do ./inc-counter.sh done for ((i=0;i<1000;i++)) ; do ./inc-counter.sh done
うまくいかない理由 • 2つのプログラムが両方クリティカルセクションに入ることがある 11 while : ; do if [
! -e lock ] ; then break fi done touch lock TMP=$(cat count) echo $((TMP + 1)) >count rm -f lock 2つのプログラムが同時にここを実行するとアウト 2つともクリティカルセクションに入り、 countの計算が狂う 例: カウンタA,Bを同時に動かす&countの初期値は0 1. countから0を読み出す 2. countに1を書き込む カウンタA 1. countから0を読み出す 2. countに1を書き込む カウンタB 終了時のcountは2であるべきだが1になる
解決方法 • 以下2つの処理を他の処理に割り込まれないよう実行(アトミック操作) 1. ロックファイルが存在するかどうかをチェック 2. 存在していれば成功、そうでなければ失敗 • シェルスクリプトからはflockコマンドが使える ◦
カウンタプログラムは以下のように実装できる inner-inc-counter.sh ▪ 12 TMP=$(cat count) echo $((TMP + 1)) >count while ((i=0;i<1000;i++)) ; do flock lock ./inner-counter.sh done “lock”ファイルを使って上記アトミック操作を実現 inner-inc-counter.sh correct-inc-counter-1000.sh
flockの内部 • flock()システムコールを使う ◦ あるファイルに対して flock(O_EX)を呼び出すと以下2つの処理をアトミックに実行 1. ファイルに対してロックがかかっているかどうかを確認 2. アンロック状態ならロックしてから正常終了、ロック済なら異常終了
◦ flock(O_UN)でアンロック ◦ 詳細は”man 2 flock”を参照 • Linuxならopen(O_CREAT|O_EXCL)を使うという手もある ◦ “その14 マウント中のファイルシステムの破壊を防ぐ小技 ”で紹介しました ▪ https://youtu.be/Hbgtt1dj9tM 13
まとめ • 排他制御: 以下のことを一つの処理からしか操作できないようにする ◦ コード上のある箇所 (クリティカルセクション )の実行 ◦ あるリソースを操作する
• 身近なところではapt系コマンドの同時実行を防ぐために使われている • シェルスクリプトならflockコマンドで排他制御ができる 14