ジョブとプログラム
コンピューターで何らかの処理を行うためには、その処理の内容を1つ1つとても細かい手順としてあらかじめ記述しておかなければなりません。これがプログラムです。プログラムを動かすことによって始めてコンピューターは意味のある処理を行うようになります。MVS(メインフレーム)ではこれをコンピューターに仕事(JOB:ジョブ)をさせると言う概念で捉えます。
そもそもコンピューターと言う機械が考えられ、開発され、発展してきた背景には人間が行ってきたさまざまな計算作業や集計処理などを少しでも早く、より大量に、そして正確に行わなければならなくなったからです。人間が仕事として行っていたことをコンピューターに行わせるのが目的ですから、コンピューターにおける処理(作業)を仕事と捉えるのは理にかなった考え方です。これがプログラムを動かすこと=ジョブ(仕事をさせる)となったわけです。
このような考え方によってMVS(実際はMVS以前のOSやコンピューターでも)はプログラムを動かすことを、ジョブを実行すると言う考え方で扱います。ジョブは人間から見た仕事の単位で、またMVSから見た最も大きな仕事の単位でもあります。
ジョブの構成
1つの仕事が複数の作業によって成り立つことはよくあることです。例えば、「会議用の資料をコピーして準備する」と言う仕事は、
- 資料を5部コピーする
- ページ順に5冊に並べ替える
- 1冊ずつホチキスで留める
というように3つの作業に分かれます。MVSのジョブも同じで1つのジョブを複数のプログラムの実行で成り立たせることができます。この場合の、1つ1つのプログラムの実行をジョブ・ステップ(JOB STEP)または単にステップと呼びます。1つのジョブは、1つまたは複数のステップで構成されます。
ステップは順番通りに実行される
MVSのジョブでは複数のステップは順序通りに実行されます。一般に1つの仕事を構成する各々の作業には、順序に基づく関連性があります。上記の例でも、資料のコピー、並べ替え、ホチキス留め、の各作業は順序通りでなければ処理できず、また同時に行うこともできません。コピーされなければ並べ替えはできないし、ページがバラバラの資料をホチキスで留めるのは仕事としては不正確です。
MVSのジョブ・ステップにも同じ考えがあてはまります。たいていの場合、先行ステップの出力データ(処理結果)を後続のステップの入力データにして、さらに別の処理を行うというようにしてデータ処理の順番にステップが並べられ、ジョブが構成されます。
典型的な例が、「プログラムの実行形式モジュールを作る」です。コンパイルしてリンカー(リンケージ・エディター)に掛けると言う2つの手順を踏みます。コンパイラーの出力がオブジェクトで、オブジェクトはリンカーの入力になります。そしてリンカーの出力が実行形式モジュールになります。コンパイルとリンクは同時にはできませんし、順番を逆にすることもできません。コンパイルしてからリンクの順で処理をした結果が、出力された実行形式モジュールで、実行形式モジュールが作成されて1つの仕事が完了します。
ジョブの種類
MVSのジョブには、OSから見た用途に応じて3つの種類があります。
JOB
1つ目が、JES(ジョブ入力サブシステム)によってスケジュールされ、イニシエーターと呼ばれるジョブの実行を行うアドレス空間によって実行されるジョブです。必要な時に実行され、多くは比較的に短時間で終了することが予定されるものです。
元々、ユーザープログラムはこのタイプのジョブとして実行され、主にバッチ処理を(あるいはバッチ処理として)行っていたことからバッチ・ジョブと呼ばれます。
基本的にMVSでのジョブはこのタイプを指します。プログラムをJOBとして実行するには、JCLをリーダーでJESに読み込ませます。
STC
2つ目はイニシエーターによらず、MVSから直接実行されるスターティッド・タスク(STCタスク)です。JOB同様JCLは使用されますが、リーダーを使わずOSのコマンドで直接MVSに実行させます。
STCタスクは主にシステムに常駐してサービスを行うプログラムを実行するために使います。STCタスクは、バッチジョブと異なり入力データを全て処理し終えたら終わるのではなく、オペレーターが指示をするまでOS内に居続け、主にMVSの機能を補完したり、MVSに無い機能を提供したりするために使われます。データベースやオンライン制御システムなどもこのタイプのジョブとして実行されます。
※STCタスクとして実行したから自動的にOS内に常駐したり、OSに無い機能を補完する訳ではありません。オペレーターの指示を受けて動くためには、そのような機能を使用したプログラムを作る必要があります。また、オペレーターの指示を受けて動くプログラムであっても必要ならばバッチ・ジョブとして実行させることができます。一般的には、STCタスクは、オペレーターの指示を受けて動くように作られたプログラムの実行に使われ、バッチ・ジョブは、オペレーターの指示によらず、まとまった量のデータを処理し終えたら終了するように作られたプログラムの実行に使われます。そういった観点で区分けしたものです。
TSU
3つ目はTSOユーザーです。対話処理を行うためにTSOにログオンすると、TSOの管理プログラムから起動されて、ログオンしたユーザー自身が1つのジョブとして扱われます。TSOからのログオフによってジョブとしても終了します。
JCL
OS/360以前のコンピューターでは、ジョブに対応したプログラムを実行させるのはオペレーターの仕事でした。オペレーターは、プログラマーが作成したプログラムを、実行指示書に基づいてプログラム・モジュールと入力データを準備し、カードリーダーやテープなどの装置にセットしてからプログラムを開始させました。プログラムが終了すれば、使い終わったデータを外し、片付け、そして次のジョブの実行指示書によって準備を始めるといった作業を繰り返します。
実際にプログラムが動く時間よりも、はるかに多くの人間による準備と後始末作業の時間が掛かり、CPUの性能が上がるにつれ深刻な問題となりました。CPUが速くなっても人間の作業時間は変わらないので、CPUの遊び時間だけが増えてしまうことになってしまいます。OSというソフトウェアは、このような無駄を少しでも減らして効率を高め、システム全体の生産性を上げる目的で誕生しました。
やがて登場したOS/360において、オペレーターを介さずにプログラマーから直接OSに「実行するプログラムと使用するデータ」を示せるようにと採用されたのが、JCL(Job Control Language:ジョブ制御言語)です。JCLを使用してジョブにおける作業の内容と使うコンピューター資源をOSに直接指示できるようになりました。言語となっていますがスクリプトの1種で、プログラマーがOSに渡す「作業指示書」です。
JCLによってオペレーターは紙の指示書によるジョブの準備から解放され、プログラマーはOSに直接指示できることになり、運用の効率と正確性が向上したことは言うまでもありません。また、OS/360で採用されたJCLの基本的な文法や機能は、現在のz/OSでもほとんど変化はなく、互換性のためとは言え当時の実装の完成度を示すものでもあります。
JCLは大きく3つの要素(JOB文、EXEC文およびDD文)で構成され、先頭が2つの//記号で始まる80バイトの固定長レコード(カードイメージ)の集合です。このJCLをリーダーで読み取らせることで、ジョブが開始されプログラムが実行されます。リーダーを介してMVSにJCLを読み取らせる操作のことを「サブミット」と呼びます。
JCLについては「JCL入門」にて解説してあります。
ローディングと実行
JCLがサブミットされジョブが開始されると、DD文で指定された資源が割り振られ、プログラムの実行が始まります。
MVSはEXEC文で指定されたプログラムを探すことから始めます。STEPLIB DD文があればそこで指定されたデータセットからプログラムを読み込みます。STEPLIBが指定されないか、指定されてもそのライブラリーにプログラムが入っていなければOSのリンク・ライブラリーから探し出します。ライブラリーに入っているプログラムはMVS用の実行可能形式になっています。実行可能形式はソース・プログラムがコンパイルされて出来上がったオブジェクト・プログラムがさらにリンケージ・エディター(リンカー)によってロード・モジュールに変換されたものです。
ロード・モジュールは命令とデータの集合であるプログラム部分(モジュール・テキスト)とプログラムの属性や大きさ、実行を始める最初の命令位置、いつどのような言語で作成されたなどの制御と管理情報の部分で構成されています。
MVSはEXEC文で指定されたプログラム(ロード・モジュール)をライブラリーに見つけるとそれをメモリー上に読み込みます。この動作をローディングと呼びます。MVSによってプログラムがローディングされ、実行の制御に必要なコントロール・ブロックが作られた後、プログラムの実行が始まります。