イチから全部作ってみよう(33)「排他制御」をトイレのアナロジーで理解する:山浦恒央の“くみこみ”な話(202)(3/3 ページ)
ソフトウェア開発の全工程を学ぶ新シリーズ「イチから全部作ってみよう」。第33回は、複数人が同時にアクセスするシステムを開発するためのプログラミングで重要になる「排他制御」をトイレに例えて説明する。
4.5 カギがかかっていたら待機する
誰かがトイレを使用中でカギが掛かっているときは、使い終わるまで待ちますね(図6)。
図6に示す通り、お父さんがトイレ使用中でカギが掛かっているため、息子は待機し続けます。お父さんがトイレから出てカギが開くと、息子はトイレに入り、再びカギを掛けます(図7)。
このように、共有資源をロックしている場合は、アンロックするまで待機します。これを、プログラムの世界では「待機(wait)」と言います。
4.6 カギがかかった状態で倒れた場合
「お母さんがトイレ使用中に体調不良で倒れた」という緊急事態を考えてみましょう(図8)。
図8の場合、カギは内側にしかありませんので、誰もカギを開けることができず永遠にトイレを使用できませんし、お母さんを助け出すこともできません。
プログラムの世界でも、ロックが開放できないまま処理が停止すると、他の処理がアンロック待ちで無限に待ち続けるという問題が発生します。これを、「ロックの開放漏れ」と言います。
この問題を防ぐため、プログラムでは、次のような対策を行います。
(1)例外処理を行って必ずアンロックする
例外(エラー)が発生した場合でも、必ずアンロックできる仕組みを作ります。例えば、try-finallyブロックを使い、finally節の中で、アンロック処理を呼び出します。これにより、正常/異常を問わずロックが開放できます。
下記に、プログラムの記載イメージを示します(リスト1)。
try: # トイレに入ってカギを掛ける(ロック処理) # 用を足す(共有資源へのアクセス処理) finally: # トイレの中で何が起きても必ずカギを開けてドアを開ける(アンロック処理)
(2)タイムアウトを設定する
一定時間内に使用できない場合は、待機を打ち切る「タイムアウト」を設定します。これは、「3分待ってもトイレが開かないので、使うのを諦める」というイメージに相当します。
5.まとめ
トイレとプログラムの話が行ったり来たりでしたので、最後に対応関係を表1にまとめます。
| トイレの話 | プログラムの世界 | プログラムの用語 |
|---|---|---|
| トイレ(家族全員で共有) | データベースの在庫数など | 共有資源 |
| 複数人が同時にトイレに入ろうとする | 複数の処理が同時に同じデータを更新しようとする | 競合状態 |
| 内側からカギを掛ける | 他の処理がアクセスできないように占有する | ロック |
| カギを開けてトイレから出る | 占有を開放する | アンロック |
| トイレ使用中は外で待つ | ロックを開放するまで処理を停止する | 待機 |
| トイレ内でカギを掛けたまま倒れる | ロックが開放できないまま処理が停止する | ロックの開放漏れ |
| 表1 トイレとプログラムの対応関係 | ||
上記が、排他制御をトイレに例えて説明したアナロジーです。
6.おわりに
今回は、排他制御の基本的なイメージをつかむため、身近な「トイレ」を例題にして説明しました。目に見えないプログラムの動きは、身近なイメージで考えることが理解への近道です。
排他制御のポイントは、下記の3つです。
- 競合状態を防ぐ:共有資源にアクセスする間はロックを掛け、他の処理を排除する
- 必ずアンロックする:例外などが発生しても、ロックが確実に開放できるように設計する
- タイムアウトを設定する:ロックの開放漏れが起きても無限に待ち続けないように、一定時間ロックが開放されない場合はエラーとして処理する
なお、今回紹介した例は、「誰かが使っている間は、他の読み書きを一切禁止する」という最もシンプルなケースです。実際のシステム開発では、読み込みは複数の処理で同時に許可しつつ、書き込み時だけ排他制御を行う手法を使うことが多くあります。
今回は排他制御をトイレに例えて解説しましたが、身の回りにある「みんなで共有して使うもの」に注目してみると、他にもたくさんの面白い例えが見つかるはずです。ぜひ、自分なりの例えを探しながら、理解を深めてみてください。
山浦先生執筆の書籍が販売中です!
本連載で取り上げた「ソフトウェア技術者のためのバグ百科事典」を大幅に加筆、修正した山浦恒央先生の書籍「ソフトウェア技術者のためのバグ検出テキスト」が日科技連出版から好評発売中です。連載でも取り上げた、「要求仕様書のバグ」「実装抜けのバグ」「テスト業務のバグ」など、バグを36種類に分類して解説しています。囲碁や将棋であれば、「相掛かり」「矢倉」「四間飛車」「藤井システム」のような戦法を網羅した内容になっています。
前著「ソフトウェア技術者のためのバグ検出ドリル」(2019年11月刊行)も好評発売中です。実際にバグを含む要求仕様書、設計書、コーディング、デバッグ、保守を具体的に取り上げ、練習問題として31問を出題しました。同書は、囲碁や将棋における「次の一手」的な問題であり、ピンポイントの場面を取り上げ、実践力を鍛えることを目的としています。
両書とも興味のある方は、Amazon.comや書店でチェックしてください!
人間環境大学 環境情報学科 教授(工学博士)
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- ≫連載「山浦恒央の“くみこみ”な話」バックナンバー
イチから全部作ってみよう(32)PythonでSQLを実行してデータベースを操作する
ソフトウェア開発の全工程を学ぶ新シリーズ「イチから全部作ってみよう」。第32回は、さらに一歩踏み込み、PythonプログラムからSQLを実行してデータベースを操作する方法を解説する。
イチから全部作ってみよう(31)SQLを操作して実際にデータベースを作ってみる
ソフトウェア開発の全工程を学ぶ新シリーズ「イチから全部作ってみよう」。第31回は、SQLの操作方法の解説をもう一歩進めた上で、実際にワインの商品データベースを作ってみる。
イチから全部作ってみよう(30)データベース操作の共通言語「SQL」を使ってみる
ソフトウェア開発の全工程を学ぶ新シリーズ「イチから全部作ってみよう」。第30回は、これまで紹介してきたデータベースに関する概念的な話から離れ、SQLを使って実際にデータベースを操作してみる。
イチから全部作ってみよう(29)3つのノート整理法からたどるRDBMSの基礎知識
ソフトウェア開発の全工程を学ぶ新シリーズ「イチから全部作ってみよう」。第29回は、お題「店長の頭の中を設計しよう」の解答例となる3つのノート整理法を基に、リレーショナルデータベース(RDBMS)の基礎知識について説明する。
イチから全部作ってみよう(28)データ設計に必要なデータベースの基本事項
ソフトウェア開発の全工程を学ぶ新シリーズ「イチから全部作ってみよう」。第28回は、データ設計に必要なデータベースの基本事項を整理する。




