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
680
シェルスクリプトで学ぶ排他制御
以下動画のテキストです。
https://youtu.be/RPKt1p2SkxY
Satoru Takeuchi
PRO
September 19, 2020
Tweet
Share
More Decks by Satoru Takeuchi
See All by Satoru Takeuchi
小学校5,6年生向けキャリア教育 大人になるまでの道
sat
PRO
8
3.4k
ファイルシステムの不整合
sat
PRO
2
130
書籍執筆での生成AIの活用
sat
PRO
2
440
ChatGPTに従って体調管理2026
sat
PRO
0
170
eBPF
sat
PRO
1
140
waruiBPF
sat
PRO
0
120
eBPFとwaruiBPF
sat
PRO
5
4.3k
Pythonのコードの気になる行でスタックトレースを出す
sat
PRO
1
110
ソースコードを読むときの思考プロセスの例 ~markdownのレンダリング方法を知りたかった2 markdownパッケージ~
sat
PRO
0
220
Other Decks in Technology
See All in Technology
20260320_JaSST26_Tokyo_登壇資料.pdf
mura_shin
0
130
脳が溶けた話 / Melted Brain
keisuke69
1
1.1k
新規事業×QAの挑戦:不確実性を乗りこなす!フェーズごとに求められるQAの役割変革
hacomono
PRO
0
180
Phase11_戦略的AI経営
overflowinc
0
1.6k
【AWS】CloudTrail LakeとCloudWatch Logs Insightsの使い分け方針
tsurunosd
0
120
やさしいとこから始めるGitHubリポジトリのセキュリティ
tsubakimoto_s
2
1.7k
TUNA Camp 2026 京都Stage ヒューリスティックアルゴリズム入門
terryu16
0
520
「捨てる」を設計する
kubell_hr
0
290
Change Calendarで今はOK?を仕組みにする
tommy0124
1
110
VSCode中心だった自分がターミナル沼に入門した話
sanogemaru
0
740
スピンアウト講座05_実践活用事例
overflowinc
0
1.3k
RGBに陥らないために -プロダクトの価値を届けるまで-
righttouch
PRO
0
110
Featured
See All Featured
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
1.9k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.2k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
110
Information Architects: The Missing Link in Design Systems
soysaucechin
0
840
KATA
mclloyd
PRO
35
15k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
160
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.3k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
1
330
Typedesign – Prime Four
hannesfritz
42
3k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
480
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
sira's awesome portfolio website redesign presentation
elsirapls
0
200
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