ページの先頭行へ戻る
Interstage Application Server V13.0.0 アプリケーション作成ガイド(CORBAサービス編)
FUJITSU Software

2.1.3 子プロセス/スレッドの生成終了処理( C, C++, Java, COBOL )

CORBAワークユニットのアプリケーションから生成される子プロセスでは、CORBA機能を使用しないことを推奨します。
CORBAワークユニットのアプリケーションから生成される子プロセスにおいてCORBA機能を使用する必要がある場合は、子プロセスに環境変数が引き継がれないようにしてください。CORBAワークユニットのアプリケーションにはInterstageによって設定されている環境変数があり、環境変数が引き継がれると子プロセスのCORBA機能が正しく動作しない可能性があります。



CORBAアプリケーションより生成し、exec系の関数でプロセスイメージを変更していない子プロセスを終了する際には、exit()ではなく、_exit() を使用してください。exit() を使用した場合、子プロセスが終了した際に親プロセスも終了したと誤認されて、その後の動作は保証されません。
また、他言語(COBOLなど)のランタイムを呼び出す場合、その言語の機能/APIでプロセスを終了させると、ランタイム内でexit()が使用される可能性があります。exec系の関数でプロセスイメージを変更していない子プロセスでは、他言語の機能/APIでプロセスを終了させないでください。
なお、exec系の関数でプロセスイメージを変更している場合は、プロセスを終了する際にexit()が使用可能です。

CORBAアプリケーションより生成した子プロセスでCORBA機能を使用する場合は、exec系の関数でプロセスイメージを変更してから、CORBA_ORB_init関数(C++ではCORBA::ORB::init関数)を発行して初期化処理を行ってください。



プロセスモードのサーバアプリケーションから子プロセスを生成する場合は、fork()を使用してください。スレッドモードのサーバアプリケーションの場合は、fork()ではなくfork1()を使用してください。

スレッドモードのサーバアプリケーション内から、さらにスレッドを生成する場合は、thr_create() の引数としてTHR_NEW_LWPおよびTHR_BOUNDフラグを指定する必要があります。



CORBA_ORB_init関数(C++ではCORBA::ORB::init関数)発行後に子プロセスを生成する場合は、_spawn系関数(_spawn関数、_spawnl関数など)は使用しないでください。_spawn系関数はハンドルなどを親プロセスから引き継ぐ仕様となっているため、CORBAサービスの制御が正常に行えなくなります。
CORBA_ORB_init関数(C++ではCORBA::ORB::init関数)発行後にプロセスを生成する場合は、CreateProcess関数を使用してください。



動作モードがSYNC_ENDのサーバアプリケーションの場合、CORBA_BOA_impl_is_ready関数(C++ではCORBA::BOA::impl_is_ready関数)復帰後に、リクエスト処理スレッドがリクエストを処理することはありませんが、OSレベルでスレッドが終了していることは保証しません。
そのため、dlopen関数で動的に組み込んだライブラリ上の関数をpthread_key_create関数などでスレッド終了時のデストラクタ関数に登録して、CORBA_BOA_impl_is_ready関数復帰後に動的に組み込んだライブラリをdlclose関数で解放した場合、解放済みのライブラリの関数をリクエスト処理スレッドが終了時に発行しようとしてプロセスが異常終了する可能性があります。デストラクタ関数の存在するライブラリは、dlclose関数で解放しないでください。



初期スレッドでpthread_exit()を発行して初期スレッドを終了させた場合、Linuxの仕様によりpsコマンドでプロセスの情報を確認すると<defunct>の表示が現れ、gcoreコマンドやstraceコマンドなどでプロセスの情報を採取することができなくなります。
gcoreコマンドやstraceコマンドなどでプロセスの情報を採取できないと、トラブルが発生した場合に調査が難しくなるため、アプリケーションを開発する場合は、初期スレッドを終了させないロジックにすることを推奨します。
たとえば、インプリメンテーションの定義で動作モードに“COMPATIBLE”を設定したサーバアプリケーションの場合、サーバアプリケーションの活性化後は初期スレッドが不要となることが一般的です。この場合、動作モードを“SYNC_END”に設定して活性化関数復帰後にプロセスを終了させるように修正するか、初期スレッドでpthread_exit()を発行せずにsleep()を無限ループするように修正します。

修正前のソース(動作モード:COMPATIBLE)
int main( int argc, char *argv[] )
{
    /* ORBの初期化処理など */
    CORBA_BOA_impl_is_ready(...); /* 活性化関数(引数は省略) */

    pthread_exit(NULL);
}
動作モードをSYNC_ENDに設定した場合の修正後のソース
int main( int argc, char *argv[] )
{
    /* ORBの初期化処理など */
    CORBA_BOA_impl_is_ready(...); /* 活性化関数(引数は省略) */

    return 0;
}
動作モードをCOMPATIBLEから変更しない場合の修正後のソース
int main( int argc, char *argv[] )
{
    /* ORBの初期化処理など */
    CORBA_BOA_impl_is_ready(...); /* 活性化関数(引数は省略) */

    while ( 1 ){
        sleep( 1000 );
    }
}