ENQとDEQは、プログラムが排他制御に使う、MVSのアセンブラー・サービス(API)の1つです。
OSの重要な機能のひとつに「資源の逐次化」があります。排他制御とも呼ばれ、メモリーやデータセットなど、複数のプログラムで取り合いになるリソースを順番に使わせるものです。複数のプログラムを同時に動かす、マルチ・タスキングをサポートするOSには欠かせないものです。
MVSでは、一般のアプリケーション・プログラムが排他制御を行うためのサービスとして、ENQとDEQというアセンブラー言語用マクロ命令を用意しています。ENQが排他制御のために資源を使う権利を得るもので、DEQは逆にその権利を解放します。
次のプログラムは、複数のタスクでメモリー内の共用領域を更新する場合のENQ/DEQを使用した排他制御の例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
: ENQ (RESQNAME,RESRNAM1,E,L'RESRNAM1,STEP),RET=USE LTR 15,15 BNZ SHORT_WAIT 排他制御に失敗したらSHORT_WAITへ飛ぶ : テーブル内データの更新処理を行う : DEQ (RESQNAME,RESRNAM1,L'RESRNAM1,STEP),RET=HAVE : : RESQNAME DC CL8'SHRTABLE' RESRNAM1 DC CL32'USER-ACCOUNT-TABLE' : |
ENQとDEQでは、排他制御の対象になる資源は、あらかじめ決められているわけではなく、サービスの利用者が自由に設定できます。プログラム内のメモリー領域でもいいし、データセット、ファイル内のレコードなど何でもかまいません。ただし、データセット全体やデータベース内のレコードなどは、プログラムが自分で直接排他制御するよりは、DDステートメントのDISPパラメーターやデータベースが提供する排他制御の機能を使うことが一般的です。
上記のサンプルでは、競合してアクセスするテーブル領域に名前を付けて排他制御の資源名にしています。資源名はQ名とR名に分かれ2階層で分類できるようになっています。ENQマクロでは、資源の名前(Q名とR名)、排他の方法(占有か共用)、排他の範囲を指定して排他制御を要求します。
排他制御の範囲はSCOPEと呼ばれ、ENQマクロではSTEP(同一空間内)、SYSTEM(同一OS内の複数空間)、SYSTEMS(複数OSにまたがる複数空間)が指定できます。
ENQで獲得した排他制御は、資源を使い終わったらすみやかにDEQによって解放しなければなりません。どの資源にどのような名前を付け、どのタイミングで排他制御を行うかは、すべてアプリケーション・プログラムのデザインとして決め、決められたとおりにプログラミングしなければなりません。MVSは、排他制御のためのメカニズムは提供しますが、アプリケーションが正しい排他制御をしているかまではチェックしません(できません)。仮に、排他制御が必要なメモリー領域をENQせずにアクセスしても、CPUはそのまま命令を実行してしまいます。あくまでも、皆が決められたルールを決められた通りに守っている、ことが前提のしくみであることを知っておく必要があります。
ENQとDEQを使うためには、最低でもプログラムはアセンブラー言語で作成される必要があります。あるいは、アセンブラー言語で排他制御用サブルーチンを作成して、それを呼び出すかです。COBOLなどで作成されたアプリケーションでは、プログラムが資源を直接排他制御することは少なく、アクセス・メソッドやデータベース、TPモニターの排他制御機能などによって間接的に排他制御を行うのが一般的です。
ENQとDEQの他、MVSにはOS自身などの制御プログラムが使う「SETLOCK」という排他制御サービスもあります。こちらは、ENQとDEQのように任意の資源を指定できず、OSがあらかじめ定めたごく少ない種類の資源のみ排他制御できますが、ENQやDEQよりはるかに少ないオーバーヘッドで処理できます。また、制御プログラムでは、メモリー内のフィールドをCPU命令によって、ハードウェアの機能によりロックする方法もとてもよく使われています。