月別アーカイブ: 2021年4月

プロセス

プロセスは異なるメモリー空間で動作するプログラムです。利用時にログインしている端末もログインプロセスといわれるプロセスの1つです。提供されるコマンドやユーザープログラムをログインプロセス上で動作させて利用していきますが、バックグランドで動かすことも可能です。start_processコマンドを使うと、指定したコマンドをバックグランドで動かすことができます。パラメータを多く指定する必要がありますが、それぞれ意味を持ちます。重要なパラメータの1つにOUTファイルの指定があります。これはバックグランドで動いた場合に出力される標準出力のファイル指定です。実行結果はこのファイルへ書き出され、結果の検証などに使われます。
ログインプロセスも標準出力を持っており、list_port_attachmentコマンドでプロセスが使用しているポートを一覧すると、最初のほうに表示されるTERMINALが相当します。つまり、コマンドを実行した結果は実行した端末に表示されるということになります。

よく利用されるバックグランドプロセスは、起動したらキューや何らかの外部要因で処理を行い、停止するまで実行し続けます。停止はユーザーがプログラムした手法(キューで停止命令などを送って処理させたりいろいろ)で行いますが、停止させるコマンドもstop_processというコマンドで用意されてます。例えば、list_usersコマンドを定期的に実行するコマンドマクロを用意してバックグランドプロセスで実行させておき、データが取れたと思ったらstop_processで停止させ、出力されたOUTファイルを解析してパフォーマンス測定を行ったりできます。
プロダクツとしてプログラミングする場合は、バックグランドで動かすプログラムを起動・停止するプログラムを用意しておき、ユーザーに提供して利用してもらう形になります。この辺りの作りこみが必要ですが、細かく作れば動作状況もわかりやすく設計できると思いますし、満足されるプログラムになるでしょう。

当然ながらstart_processコマンドではなく、APIとしてのルーチンも提供されております。s$start_processがそうで、これもパラメータを多く必要としますがユーザープログラムから任意のプログラムを起動させることが可能です。また、プロセスを扱うプログラムはプロセスが起動時に割り当てられる「プロセスID」を使うことで当該プロセスの情報取得・操作も可能です。当然自分がいま使っているログインプロセスの情報も取れますし、異なるプロセスの情報も取得可能です。ただし、アクセス権がないと拒否されます。

プロセス間通信:シグナル

Stratus VOSもLinuxなどでも存在するシグナルをサポートしてます。s$enable_condition、s$signal_conditionなどのAPIが提供されており、シグナルを受け取ると自前のルーチンへ制御を渡すことができます。PL/Iを使用する場合、言語としてシグナルハンドラーを記述することができますので、言語の機能で実装するのもアリかと思います。

シグナルは使いどころが難しく、何でも処理しようとルーチンを書いた場合、エラー調査が難しくなったり、情報を取り損ねるとデバッグが困難になるケースがあります。プロセスは障害などでシグナルを発生させた場合、デフォルト動作にて動作するようになってます。大抵は端末につながるプロセスなら継続するか停止するかなどの問い合わせを行うようになってます。常駐型のプロセスならキープモジュール(コアダンプ)を作成して停止するようになってます。デバッガを起動してデバッグもできますし、エラーメッセージから状況を判断することも可能です。これらのシグナルも自前のルーチンで処理しようとすると二度手間になる場合がほとんどかと思われます。
まあ、常時別のプロセスに状況を送るようなプログラムで、異常状態を検知した場合に当該プロセスへ通知させてから停止なんてプログラムの場合にはいいのかも。

プロセス間通信:共有メモリー

異なるプロセス間でメモリーを共有する手法として共有メモリー(SVM)が提供されます。Linuxなどで言う共有メモリと同じです。ファイルシステムとプログラムもメモリアドレスを合わせておくことで利用可能となります。
プログラムはSVMへ接続すれば通常のメモリアクセス(構造体や配列など)と区別なくアクセスができます。複数プロセスが同時にアクセスしますから、メモリの排他制御の問題が発生します。各プログラム間で特定領域をアクセスする時に排他制御をそれぞれ行う必要があります。OSのバージョンによっていろいろ変わりましたが、自分が知りうるバージョンではスピンロックのサブルーチンが提供されました。この参照場所を合わせてロック・アンロックすることで排他制御を可能にしてました。

プロセス間通信:キュー

キューは先入れ先出しのプロセス間通信です。送る側をリクエスター、受け取り側をサーバと名付けており、通常はリクエスター・サーバ構造となります。キューはメッセージキュー、1Wayサーバキュー、2Wayサーバキュー、ダイレクトキューが存在します。よく使うのは最初の2つ、場合によっては2Wayサーバキューも利用します。APIはs$msg_xxxという名前のルーチンが提供されてます。

メッセージキューはサーバが動作してようかしてまいが送り込めるキューです。プリンターのキューによく使われており、印刷のリクエストを送ってスプーラーが動作してれば印刷されますし、動作してなければリクエストは溜まっていくという感じです。ファイルI/Oに類似しますが、先入れ先出し機能で最初に投入された要求から処理できるのが大きなメリットです。

1/2Wayサーバキューはサーバが動作して受け入れ可能になってる場合に利用できます。サーバはメッセージが到着すると受信処理を行いメッセージを受け取ります。1Wayサーバキューはリクエスタがメッセージを送るとリクエスタ側は処理が完了します。一方的に送り付けるような処理に向いてます。2Wayサーバキューはリクエスタがメッセージを送信しても、サーバが受け取り完了の通知を行わないと処理完了を待たされます。確実に受け渡しを行いたい場合に使われます。

ダイレクトキューはあまり使ったことがないので各自で調べてみてください。
Stratus VOSにおいて、キューは重要な機能の1つで使いこなせると高度なプログラミングが可能です。