ATTACHマクロのEPまたはEPLOCキーワードで指定できるのは、ロードモジュール・メンバーの名前です。したがって、この点だけで考えるとATTACHできるのはLINKやXCTLのように独立したロードモジュールになっているプログラムになってしまいます。しかしながら、タスクを分けるが故にプログラムも分割しなければならないのは不便です。タスク構造とプログラム構造が一対一になっていなければならない決まりはありません。自由度はもっと高いのです。
では、静的リンクされた単純構造プログラム(06.1 プログラムのローディングと実行(LOAD,LINKとXCTL)を参照)内の別CSECTのプログラムをサブタスクとしてATTACHしたい場合はどうすればいいのでしょうか?そのためには2つの方法があります。
ATTACHしたいプログラムがCSECTで定義されていれば、バインダーでモジュールをリンクする際にCSECT名メンバーの別名として追加することができます。割り当てた別名を、EPあるいはEPLOCキーワードで指定すればATTACHすることができます。
1 2 3 4 5 6 7 8 9 10 11 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- //LKD EXEC PGM=IEWL,PARM=('LIST,LET,MAP,XREF') //SYSPRINT DD SYSOUT=* //SYSUT1 DD UNIT=SYSALLDA,SPACE=(TRK,(80,20)) //SYSLIB DD DISP=SHR,DSN=MY.LOAD //SYSLMOD DD DISP=SHR,DSN=MY.LOAD //SYSLIN DD DSN=*.ASM.SYSLIN,DISP=(OLD,DELETE) // DD * ALIAS SUBTASK3 ← ALIAS制御文で別名を付ける(ATTACHしたいCSECT名) NAME MAINTASK(R) ← 主となるメインプログラム名 // |
もう1つはIDENTIFYマクロを使い、プログラム内で動的に入口点を追加する方法です。LOADマクロなどによって既にメモリー内にローディングされたモジュール内(EXECステートメントのPGMパラメーターで指定されたプログラムも含む)であれば、任意のアドレスを入口点として追加できます。
入口点の追加(IDENTIFY)
1 2 3 4 5 6 7 8 9 10 11 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- 【メインプログラム】 : L R1,=A(SUBTASK1) LOAD SUB PROGRAM ENTRY IDENTIFY EP=SUBTASK1,ENTRY=(1) ASSIGN ALIAS NAME MVI EOTECB,0 CLEAR SYNCHRONOUS ECB ATTACH EP=SUBTASK1, EXECUTE MOD=SUBTASK1 UNDER + PARAM=PARM1, NEW TASK WITH PARM=PARM1+ ETXR=EOTEXIT : : |
IDENTIFYを使用する場合、対象となる入口点アドレスは必ずしもCSECTやENTRYで定義した外部参照可能なラベル名である必要はありません。また、同じ入口点に複数の名前を付けることもできます。同じプログラムを複数のタスクで共用するような場合、IDENTIFYによって各タスクにタスク名を割り当てるような使い方もできます。IDENTIFYを使えば、複数のCSECTを結合した単一のプログラム・モジュールで提供あるいは運用されるプログラムにおいて、モジュール内の任意のCSECTや場所をプログラム・モジュールとしてLINKやATTACHすることができます。
バッチ・ユーティリティーの呼び出しにATTACHを使う
多くのバッチ・ユーティリティーは、プログラムから呼び出すこともできます。しかし、同じユーティリティーをデータを変えて繰り返し何度も続けて呼び出す場合は、LINKではなくATTACHを使う方がよい場合があります。ユーティリティーの中には、使用した作業域を解放しないまま終了してしまうものもあるからです。バッチのジョブ・ステップとしてJCLで直接実行する場合では問題になりませんが、プログラムから呼び出す場合はユーティリティーが終了しても呼び出したプログラムは終了しないため、リージョン内の解放されない領域はデッドエリアとして残ってしまいます。これは、同じタスクでユーザープログラムとユーティリティーを実行する事になるからです。LINKではなくATTACHによってユーティリティーを実行し、かつATTACH時にサブプール0を共用しない指定をすれば、ユーティリティー・タスクの終了時に未解放の作業域があってもOSがクリーンアップし解放してくれます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- FTPクライアントの呼び出し例 : MVI FTPECB,0 CLEAR EOT ECB LA R1,FTPPLIST GR1 --> EXEC PLIST ATTACH EPLOC=FTPNAME, ATTACH FTP UTILITY TASK M002 + ECB=FTPECB, + SZERO=NO,JSTCB=YES NEED JSTCB=YES UNDER Z/OS TO + AVOID RETAIN SP252 FOR SUBTASK + USE.(EG. QSAM BUFFER POOL...) ST R1,FTPTCB SAVE TCB ADDRESS : : WAIT ECB=FTPECB SYNCHRONIZE FTP TASK END L RF,FTPECB GET COMPLETION CODE N RF,=A(X'3FFFFFFF') DROP CONTROL BITS : DETACH FTPTCB PURGE FTP TASK TCB : : : FTPNAME DC CL8'FTP' FTP PROGRAM NAME FTPTCB DC A(0) FTP SUBTASK TCB FTPECB DC F'0' FTP SUBTASK EOT ECB FTPPLIST DC A(FTPPARM+X'80000000') PLIST FOR FTP CALL FTPPARM DC H'5',CL100'(EXIT' FTP EXEC PARAMETER |
FTPクライアントの呼び出し例です。タスク終了の待ち合わせには非同期出口ルーチンではなくECBを使用しています。このサンプルでは、ATTACHの目的は処理の効率化ではなくリソースの独立性を保つためなので、ATTACH後に実行されるユーティリティーと非同期に処理を行う必要はありません。そのため、ATTACH後は単純にユーティリティーの終了を待ち合わせればよいのです。
ユーティリティーの中にはリエントラントに設計されたものがあります。例えば、IDCAMSです。AMSユーティリティーの場合は、ATTACHではなくLINKでもAMSが使用したリソースが残ってしまうような問題を経験したことがありませんが、AMS以外のユーティリティーをLINKマクロなどで連続して呼び出した場合に、長時間の実行後やがてストレージ不足に陥ったり、異様に大量のメモリーを使ったことになっているような場合はATTACHを利用してサブタスクとして実行する方法も有用です。