業務システム開発手法の「ユニケージ」では、データベース管理システムやフレームワークなどを使わずにシステムを構築します。システムの中身が見えやすい分、仕組みやルールを理解していないと正しい開発ができません。第5回は、排他制御について紹介します。
コンピュータ上で稼働している複数のプロセスから利用可能なファイルやデータベースなどの共通の資源がある場合、データの整合性を維持するために一つの資源に対して複数のプロセスが同時にアクセスしても問題が生じないように制御する必要があります。
この制御が行われず資源に対して各プロセスが自由にアクセスできる状態の場合、データの整合性が保たれなかったり、資源そのものが消失したりする可能性があります。
このような事態を防ぐために、あるプロセスが資源に対して書き込み中の場合、別のプロセスからの書き込みや読み込みを禁止します。書き込みが終わったら、別のプロセスの書き込
みや読み込みを許可します。この仕組みを「排他制御」と呼びます。
排他制御の方式には「ロック」「ミューテックス」「セマフォ」などがあります。
ロックは、共有資源にロックをかけて複数のプロセスからアクセスさせない方式です。このロックには「専有ロック」と「共有ロック」といった概念があります。専有ロックは、自分のプロセ
ス以外からの読み込みも書き込みもできない方式です。共有ロックは、自他共に読み込みができますが、他のプロセスからの書き込みを禁止する方式です。
そのほか、「悲観ロック」と「楽観ロック」もあります。悲観ロックは、同じデータを他のプロセスが頻繁に更新するであろうという悲観的な考え方に基づく排他制御方式です。楽観ロックは、頻繁に同時アクセスが起きないだろうという楽観的な考え方に基づく排他制御方式です。システムを構築する場合、悲観ロックなのか、楽観ロックなのかを把握しておかなければいけません。
ミューテックスは、「使用中」と「未使用」の2種類を用いてアクセス状態を判断する排他制御方式です。
セマフォは、セマフォ変数やセマフォファイルに、同時アクセスできる数や状態に格納して管理し、その数や状態に基づいて共有資源に対する排他制御を実施する方式です。
ユニケージでは、三つ目のセマフォのような排他制御を用います。セマフォファイルとなるロックファイルが作成されていない状態を確認し、書き込みなどの処理が競合しないようにあるプログラムがロックファイルを作成します。ロックファイルが存在する間は、他のプログラムは読み込みや書き込みの操作を行わずに待機します(図1)。この区間を「排他区間」と呼びます。
プログラムの処理が終了してロックファイルの消去が確認できたら、他のプログラムの読み込みや書き込みの操作が可能になります。
ユニケージでは、このような排他制御を、システム設計者が定義したルールを基づいてシェルスクリプトのプログラム内に記述します。
データベースのロックやコミットなどは、データを直接更新する際の排他制御に用いられます。一方、ユニケージではファイル内に保存したデータを更新しません。ファイルを新しく作成したり、追記したりすることでデータ更新を実現します。そのため、普段は排他制御を使わず、排他制御においては独特な方法を採用しています。
ユニケージの専用コマンド群「usp Tukubai」には、排他制御を実施するコマンドとして「ulock」が用意されています。このコマンドで、ロックファイルの作成と確認を実施して排他制御を実現します。
ulockコマンドは、シェルスクリプトのプログラム内で図2のように用います。
3行目の「lock」がロックファイルで、
1 |
if ulock lock; then |
によりlockファイルが存在しない場合は、lockファイルを作成して8行目の「fi」との間の処理を実行します。存在する場合は、lockファイルが消去されるまでifとの間の処理を待たせます。
lockファイルは、処理が終了した後で7行目のように「rm」コマンドなどで消去しなくてはいけません。また、エラーなどで7行目が実行されなかった場合にデッドロック状態になるので注意してください。
ulockコマンドには、表1のオプションが用意されています。
「–timeout」と「–invalid」は、前述したデッドロックによって処理が停滞することを避けるためのオプションです。–invalidオプションを指定しない場合は、60秒でロックファイルを削除します。時間ではなく、「-1」を指定すると、削除せずにロックファイルの削除を永遠に待ちます。
著者:田渕 智也、高橋 未来哉
※本記事は、シェルスクリプトマガジン Vol.86(2023年10月号)に掲載した記事からの転載です。