前へ | 次へ | 目次 | 索引 |
HP C RTL では,OpenVMS 例外を使用して setjmp関数と longjmp関数をインプリメントしています。 longjmp関数を呼び出すと, C$_LONGJMP OpenVMS 例外が通知されます。 C$_LONGJMP 例外がユーザ例外ハンドラによって妨害されるのを防止するには, LIB$ESTABLISH を呼び出す代わりに, VAXC$ESTABLISHルーチンを使用してユーザ OpenVMS 例外ハンドラを設定します。 C$_LONGJMP ニーモニックは <errnodef.h>ヘッダ・ファイルに定義されています。
C プログラムで OpenVMS 例外ハンドラと UNIX シグナルを使用する場合は,表 4-4 (VAX only) および表 4-5 (Alpha only) に示した OpenVMS 例外を受け付けて再通知するように, OpenVMS 例外ハンドラを準備する必要があり,さらに HP C RTL の将来のバージョンで導入される可能性のある C$ 機能例外や C$_LONGJMP 例外も受け付けるようにしなければなりません。これは,UNIX シグナルがコンテキストでグローバルであるのに対し, OpenVMS 例外がスタック・フレーム・ベースだからです。
したがって,OpenVMS 例外ハンドラは, main ルーチンの HP C RTL 例外ハンドラより前に, UNIX シグナルに対応する例外を常に受け取ります。 OpenVMS 例外を再通知することにより, HP C RTL 例外ハンドラは例外を受け取ることができます。 OpenVMS 例外をインターセプトすることも可能ですが,その場合は,対応する UNIX シグナルを禁止します。
名前 | OpenVMS 例外 | シグナルを生成するイベント | コード |
---|---|---|---|
SIGABRT | SS$_OPCCUS | abort 関数 | -- |
SIGALRM | SS$_ASTFLT | alarm 関数 | -- |
SIGBUS | SS$_ACCVIO | アクセス違反 | -- |
SIGBUS | SS$_CMODUSER | 変更モード・ユーザ | -- |
SIGCHLD | C$_SIGCHLD | 子プロセスの停止 | -- |
SIGEMT | SS$_COMPAT | 互換性モード・トラップ | -- |
SIGFP | SS$_DECDIV | 10 進数除算トラップ | FPE_DECDIV_TRAP |
SIGFPE | SS$_DECINV | 10 進数不正オペランド・トラップ | FPE_DECINV_TRAP |
SIGFPE | SS$_DECOVF | 10 進数オーバフロー・トラップ | FPE_DECOVF_TRAP |
SIGFPE | SS$_HPARITH | 0 による浮動小数点/ 10 進数除算 | FPE_FLTDIV_TRAP |
SIGFPE | SS$_HPARITH | 浮動小数点オーバフロー・トラップ | FPE_FLTOVF_TRAP |
SIGFPE | SS$_HPARITH | 浮動小数点アンダフロー・トラップ | FPE_FLTUND_TRAP |
SIGFPE | SS$_HPARITH | 整数オーバフロー | FPE_INTOVF_TRAP |
SIGFPE | SS$_HPARITH | 不正なオペランド | FPE_INVOPR_TRAP |
SIGFPE | SS$_HPARITH | 不正確な結果 | FPE_INXRES_TRAP |
SIGFPE | SS$_INTDIV | 0 による整数除算 | FPE_INTDIV_TRAP |
SIGFPE | SS$_SUBRNG | 範囲外の添字 | FPE_SUBRNG_TRAP |
SIGFPE | SS$_SUBRNG1 | 範囲外の添字 1 | FPE_SUBRNG1_TRAP |
SIGFPE | SS$_SUBRNG2 | 範囲外の添字 2 | FPE_SUBRNG2_TRAP |
SIGFPE | SS$_SUBRNG3 | 範囲外の添字 3 | FPE_SUBRNG3_TRAP |
SIGFPE | SS$_SUBRNG4 | 範囲外の添字 4 | FPE_SUBRNG4_TRAP |
SIGFPE | SS$_SUBRNG5 | 範囲外の添字 5 | FPE_SUBRNG5_TRAP |
SIGFPE | SS$_SUBRNG6 | 範囲外の添字 6 | FPE_SUBRNG6_TRAP |
SIGFPE | SS$_SUBRNG7 | 範囲外の添字 7 | FPE_SUBRNG7_TRAP |
SIGHUP | SS$_HANGUP | データ・セット・ハングアップ | -- |
SIGILL | SS$_OPCDEC | 予約命令 | ILL_PRIVIN_FAULT |
SIGILL | SS$_ROPRAND | 予約オペランド | ILL_RESOP_FAULT |
SIGINT | SS$_CONTROLC | OpenVMS Ctrl/C 割り込み | -- |
SIGIOT | SS$_OPCCUS | カスタマ予約 op コード | -- |
SIGKILL | SS$_ABORT | 外部シグナルのみ | -- |
SIGQUIT | SS$_CONTROLY | raise 関数 | -- |
SIGPIPE | SS$_NOMBX | メールボックスなし | -- |
SIGSEGV | SS$_ACCVIO | 長さ違反 | -- |
SIGSEGV | SS$_CMODUSER | 変更モード・ユーザ | -- |
SIGSYS | SS$_BADPARAM | システム呼び出しに対する不正な引数 | -- |
SIGTERM | インプリメントされていない | -- | -- |
SIGTRAP | SS$_BREAK | ブレークポイント・フォルト・インストラクション | -- |
SIGUSR1 | C$_SIGUSR1 | raise 関数 | -- |
SIGUSR2 | C$_SIGUSR2 | raise 関数 | -- |
SIGWINCH 1 | C$_SIGWINCH 2 | raise 関数 | -- |
|
例 4-1 は, signal, alarm, pause関数の動作方法を示しています。また,プログラムの終了を防止するために,シグナルを検出するようにシグナル・ハンドラを設定する方法も示しています。
例 4-1 プログラムの一時停止と再開 |
---|
/* CHAP_4_SUSPEND_RESUME.C */ /* This program shows how to alternately suspend and resume a */ /* program using the signal, alarm, and pause functions. */ #define SECONDS 5 #include <stdio.h> #include <signal.h> int number_of_alarms = 5; /* Set alarm counter. */ void alarm_action(int); main() { signal(SIGALRM, alarm_action); /* Establish a signal handler. */ /* to catch the SIGALRM signal.*/ alarm(SECONDS); /* Set alarm clock for 5 seconds. */ pause(); /* Suspend the process until * * the signal is received. */ } void alarm_action(int x) { printf("\t<%d\007>", number_of_alarms); /* Print the value of */ /* the alarm counter. */ signal(SIGALRM, alarm_action); /* Reset the signal. */ alarm(SECONDS); /* Set the alarm clock. */ if (--number_of_alarms) /* Decrement alarm counter. */ pause(); } |
例 4-1 から次の出力が生成されます。
$ RUN EXAMPLE <5> <4> <3> <2> <1> |
HP C Run-Time Library (RTL) では, HP C プログラムからサブプロセスを生成するための関数が提供されます。サブプロセスを生成するプロセスを親と呼び,生成されるサブプロセスを子と呼びます。
親プロセスの内部で子プロセスを生成するには, exec関数 ( execl, execle, execv, execve, execlp, execvp) および vfork関数を使用します。その他にも,親プロセスと子プロセスがプロセス間でデータの読み書きを実行するための関数 ( pipe) や 2 つのプロセスの同期をとるための関数 ( wait) などもあります。この章では,これらの関数のインプリメントの方法と使用方法について説明します。
親プロセスは子プロセスの内部で,同期的または非同期的に HP C プログラムを実行できます。同時に実行できる子プロセスの数は,システムの各ユーザに対して設定されている /PRCLM ユーザ登録クォータによって決定されます。サブプロセスの使用に影響を与える可能性のあるその他のクォータとしては, /ENQLM (キュー・エントリ・リミット),/ASTLM (AST 待ちリミット), /FILLM (オープン・ファイル・リミット) があります。
この章では,サブプロセス関数について説明します。 表 5-1 は, HP C RTL で提供されるすべてのサブプロセス関数を示しています。各関数の詳細については,『HP C ランタイム・ライブラリ・リファレンス・マニュアル (下巻)』「リファレンス・セクション」を参照してください。
関数 | 説明 |
---|---|
子プロセスの生成 | |
system | コマンド・プロセッサによって実行される文字列をホスト環境に渡す。 |
vfork | 独立した子プロセスを生成する。 |
exec 関数 | |
execl,execle,execlp
execv,execve,execvp |
子プロセスの内部で起動されるイメージの名前を渡す。 |
プロセスの同期化 | |
wait , wait3 , wait4 , waitpid | 値が子から返されるまで,親プロセスを一時停止する。 |
プロセス間通信 | |
pipe | 親プロセスと子プロセスの間の通信を可能にする。 |
子プロセスは,OpenVMS LIB$SPAWN RTL ルーチンと HP C 関数によって生成されます (LIB$SPAWN の詳細については, VMS Run-Time Library Routines Volume を参照してください)。 LIB$SPAWN を使用すると,複数レベルの子プロセスを生成できます。親から生成された子がさらに子を生成することができます。生成できるレベルは,この章の冒頭で説明したユーザ登録クォータで認められている上限値までです。
子プロセスは他の HP C プログラムだけを実行できます。他のネイティブ・モードの OpenVMS 言語は,プロセス間で通信するために HP C の機能を共用しません。プロセス間で通信する場合,他の言語は同じ機能を使用しません。親プロセスは,DCL など,弊社がサポートするコマンド言語インタプリタ (CLI) のもとで実行しなければなりません。親を独立プロセスとして実行したり,ユーザ指定 CLI の制御のもとで実行することはできません。
DECC$DETACHED_CHILD_PROCESS 機能論理名を有効にすると,子プロセスが,サブプロセスではなく,デタッチされたプロセスとして生成されます。この機能のサポートには,制限があります。場合によっては,コンソールが親プロセスと,デタッチされたプロセスで共用できず, execが失敗することがあります。
親プロセスと子プロセスは, 図 5-1 に示すようにメールボックスを通じて通信します。このメールボックスは,子が実行されるコンテキストを転送します。このコンテキスト・メールボックスは,親がオープンしたすべてのファイルの名前やファイル記述子,それらのファイル内での現在の位置など,親から継承する情報を子に渡します。子イメージが終了すると,メールボックスは親によって削除されます。
図 5-1 親プロセスと子プロセスの間の通信リンク
vfork関数と exec関数によって作成されるメールボックスは一時的なものです。このメールボックスの論理名は VAXC$EXECMBX であり, HP C RTL で使用するために予約されています。 |
メールボックスは 512 バイトの最大メッセージ・サイズおよび 512 バイトのバッファ・クォータで作成されます。これらの RTL 関数を使用してメールボックスを作成するには,TMPMBX 特権が必要です。 TMPMBX は DCL コマンド PRINT および SUBMIT で必要とされる特権であるため,システムの大部分のユーザはこの特権を保有しています。保有しているシステム特権を確認するには, SHOW PROCESS/PRIVILEGES コマンドを入力します。
これらのメールボックスの属性を変更することはできません。メールボックスの詳細については, VMS I/O User's Reference Volume を参照してください。
5.2 exec 関数
子プロセスで HP C イメージを実行するために呼び出すことのできる exec関数は 6 つあります。これらの関数では,戻りアドレスを設定するために vforkがあらかじめ呼び出されていることが必要です。 exec関数は,親プロセスで vforkが呼び出されていない場合,その関数を呼び出します。
vforkが親で呼び出されると, exec関数は親プロセスに戻ります。 vforkが exec関数によって呼び出されると, exec関数はその関数自体に戻り,子プロセスが終了するのを待ち,その後で親プロセスを終了します。 exec関数は,親が vforkを呼び出して戻りアドレスを保存しない限り,親プロセスに戻りません。
OpenVMS バージョン 7.2 で, exec関数は実行可能イメージまたは DCL コマンド・プロシージャを起動するように拡張されました。ファイル拡張が file_name 引数に指定されていない場合は,この関数はまずファイル拡張が .EXE であるファイルを検索し,次にファイル拡張が .COM であるファイルを検索します。同じ名前の実行可能イメージとコマンド・プロシージャの両方が存在する場合は,コマンド・プロシージャを強制的に起動するために, .COM ファイル拡張を指定する必要があります。
DCL コマンド・プロシージャの場合は, exec関数は, P1,P2,...パラメータなど, exec呼び出しに指定した最初の 8 つの arg0, arg1,... 引数をコマンド・プロシージャに渡します。その場合,大文字と小文字の区別は保持されます。
UNIX ベースのシステムと異なり, HP C RTL の exec関数は,指定された実行可能イメージまたはコマンド・プロシージャが存在するかどうか,またこれらを起動および実行できるがどうかを常に判断できるわけではありません。したがって, exec関数は,子プロセスが指定されたファイルを実行できない場合でも,正常終了したように見えることがあります。
親プロセスへ返される子プロセスの状態は,エラーが発生したことを示します。このエラー・コードは, wait関数ファミリのいずれかの関数を使用することにより検索できます。
OpenVMS システムの HP C RTL の vfork関数と exec関数は, UNIX システムの場合と異なる方法で動作します。
プログラマの場合,次の重要な相違点に注意してください。
|
前へ | 次へ | 目次 | 索引 |