COBOL を使用した Oracle Tuxedo アプリケーションのプログラミング

     前  次    新しいウィンドウで目次を開く     
ここから内容の開始

マルチスレッドおよびマルチコンテキスト アプリケーションのプログラミング

ここでは、以下の内容について説明します。

 


マルチスレッドおよびマルチコンテキスト アプリケーションのプログラミングに対するサポート

Oracle Tuxedo システムでは、次のアプリケーションがサポートされています。

お使いのオペレーティング システムで POSIX スレッド関数と共にほかのスレッド関数がサポートされている場合は、POSIX スレッド関数を使用することをお勧めします。この関数を使用すると、後でコードをほかのプラットフォームに簡単に移植できます。

お使いのプラットフォームでカーネルレベルのスレッド パッケージ、C 言語の関数、または POSIX 関数がサポートされているかどうかを確認するには、『Oracle Tuxedo システムのインストール』で、使用しているオペレーティング システムのデータ シートを参照してください。

マルチスレッドおよびマルチコンテキスト アプリケーションに関するプラットフォーム固有の検討事項

多くのプラットフォームには、マルチスレッドおよびマルチコンテキスト アプリケーション固有の要件があります。プラットフォーム固有の要件については、『Oracle Tuxedo システムのインストール』に説明があります。お使いのプラットフォームの要件については、該当するデータシートを参照してください。

関連項目

 


マルチスレッドおよびマルチコンテキスト アプリケーションの計画と設計

ここでは、以下の内容について説明します。

 


マルチスレッドおよびマルチコンテキストとは

Oracle Tuxedo システムでは、単一のプロセスで複数のタスクを同時に実行できます。このようなプロセスを実装するプログラミング手法はマルチスレッドおよびマルチコンテキストと呼ばれます。この節では、これらの手法に関する基本事項について説明します。

マルチスレッドとは

マルチスレッドとは、1 つのプロセスに複数の実行単位が含まれている処理方法です。マルチスレッド アプリケーションでは、同じプロセスから同時に複数の呼び出しを行うことができます。たとえば、個々のプロセスが 1 つの未終了の tpcall(3c) に制限されることはありません。

サーバのマルチスレッドでは、アプリケーション生成のスレッドがシングルコンテキスト サーバで使用される場合を除き、マルチコンテキストが必要です。マルチスレッドのシングルコンテキスト アプリケーションを作成する唯一の方法は、アプリケーション生成のスレッドを使用することです。

Oracle Tuxedo システムでは、C 言語で記述されたマルチスレッド アプリケーションがサポートされています。COBOL 言語のマルチスレッド アプリケーションはサポートされていません。

次の図は、マルチスレッド クライアントが 3 つのサーバに対して同時に呼び出しを行う方法を示しています。

図 10-1 マルチスレッド プロセスのサンプル

マルチスレッド プロセスのサンプル

マルチスレッド アプリケーションでは、同じサーバで複数のサービス ディスパッチ スレッドを使用できるので、アプリケーションに対して起動するサーバ数が少なくて済みます。

次の図は、異なるクライアントに対して、サーバ プロセスが同時に複数のスレッドをディスパッチする方法を示しています。

図 10-2 1 つのサーバ プロセスによる複数のサービス スレッドのディスパッチ
1 つのサーバ プロセスによる複数のサービス スレッドのディスパッチ

マルチコンテキストとは

コンテキストはドメインへの対応付けです。マルチコンテキストを使用すると、1 つのプロセスで次のいずれかが可能になります。

マルチコンテキストは、クライアントとサーバの両方で使用できます。サーバでマルチコンテキストを使用すると、マルチスレッドも使用することになります。

コンテキストの特徴の詳細については、次のいずれかの節で「コンテキストの属性」を参照してください。

Oracle Tuxedo システムでは、C 言語または COBOL 言語のいずれかで記述されたマルチコンテキスト アプリケーションがサポートされています。ただし、サポートされるマルチスレッド アプリケーションは、C 言語で記述されたものだけです。

次の図は、ドメイン内でのマルチコンテキスト クライアント プロセスの動作を示しています。矢印はサーバへの未終了の呼び出しを表します。

図 10-3 2 つのドメイン内でのマルチコンテキスト プロセス

2 つのドメイン内でのマルチコンテキスト プロセス

マルチスレッド アプリケーションまたはマルチコンテキスト アプリケーションのライセンス

ライセンスの関係で、各コンテキストは 1 人のユーザとしてカウントされます。1 つのコンテキストで複数のスレッドを使用するために、ライセンスを追加する必要はありません。次に例を示します。

関連項目

 


マルチスレッドおよびマルチコンテキスト アプリケーションの利点と問題点

マルチスレッドとマルチコンテキストを適切な状況で使用すると、Oracle Tuxedo アプリケーションのパフォーマンスを向上できます。ただし、これらの手法を取り入れる前に、潜在的な利点と問題点について理解しておくことが大切です。

マルチスレッドおよびマルチコンテキスト アプリケーションの利点

マルチスレッドおよびマルチコンテキスト アプリケーションには、以下の利点があります。

アプリケーションで、クライアント スレッドが Microsoft Internet Information Server API または Netscape Enterprise Server インタフェース (NSAPI) によって生成される場合、これらのツールの機能を最大限に利用するにはマルチスレッドが不可欠です。ほかのツールについても同じことが言えます。

マルチスレッドおよびマルチコンテキスト アプリケーションの問題点

マルチスレッドおよびマルチコンテキスト アプリケーションには、以下の問題点があります。

関連項目

 


クライアントでのマルチスレッドとマルチコンテキストの動作

マルチスレッドおよびマルチコンテキスト アプリケーションがアクティブの場合、クライアントのライフサイクルは次の 3 つのフェーズから構成されます。

起動フェーズ

起動フェーズでは、次の操作が行われます。

注意 : Oracle Tuxedo システムから独立して動作するスレッドが存在する場合もあります。ここでは、そのようなスレッドについては説明していません。

クライアント スレッドの複数コンテキストへの参加

Oracle Tuxedo マルチコンテキスト アプリケーションのクライアントは、次の規則に従う限り、複数のアプリケーションに対応付けることができます。

クライアントが複数のコンテキストに参加するには、TPINFO データ型の flagsTPMULTICONTEXTS フラグを設定して、tpinit(3c) 関数を呼び出します。

TPMULTICONTEXTS フラグを設定して tpinit() 関数が呼び出されると、アプリケーションとの新しい対応付けが生成され、スレッドに対するカレントの対応付けが指定されます。新しい対応付けが生成される Oracle Tuxedo ドメインは、TUXCONFIG または WSENVFILE/WSNADDR 環境変数の値で決定されます。

クライアント スレッドの既存のコンテキストへの切り替わり

多くの ATMI 関数はコンテキスト単位で動作します。このような ATMI 関数のリストについては、「マルチスレッド クライアントでのコンテキスト単位の関数とデータ構造体」を参照してください。コンテキスト単位で動作するには、ターゲット コンテキストが現在のコンテキストであることが必要です。クライアントは複数のコンテキストに参加できますが、状況とスレッドにかかわらず現在のコンテキストになることができるコンテキストは 1 つだけです。

アプリケーション内でタスクの優先順位が移り、ほかの Oracle Tuxedo ドメインと通信する必要が発生した場合、あるコンテキストから別のコンテキストにスレッドを再割り当てした方がよい場合があります。

そのような場合、あるクライアント スレッドが tpgetctxt(3c) を呼び出し、返された現在のコンテキストを値として持つハンドルを別のクライアント スレッドに渡します。2 番目のスレッドは tpsetctxt(3c) を呼び出し、最初のスレッドで tpgetctxt(3c) から受け取ったハンドルを指定して、現在のコンテキストとの対応付けを確立します。

目的のコンテキストとの対応付けが確立されると、2 番目のスレッドはコンテキスト単位で動作する ATMI 関数を使用してタスクを実行できるようになります。詳細については、「マルチスレッド クライアントでのコンテキスト単位の関数とデータ構造体」を参照してください。

作業フェーズ

このフェーズでは、各スレッドによって処理が行われます。次は、行われる処理の例です。

サービス要求

スレッドは、同期要求の場合は tpcall(3c)、非同期要求の場合は tpacall(3c) を呼び出して、サーバに要求を送ります。tpcall() で要求を送った場合、以降操作を行わなくても応答を受け取ることができます。

サービス要求に対する応答

tpcall(3c) でサービスの非同期要求を送った場合、同じコンテキスト内のスレッドは tpgetrply(3c) を呼び出して応答を受け取ります。このスレッドは、要求を送ったスレッドと同じスレッドではない場合もあります。

トランザクション

あるスレッドがトランザクションを開始すると、そのスレッドのコンテキストを共有するすべてのスレッドでそのトランザクションが共有されます。

コンテキスト内の多くのスレッドでトランザクションに関する処理が行われますが、トランザクションをコミットまたはアボートできるのは 1 つのスレッドだけです。トランザクションをコミットまたはアボートするスレッドは、トランザクションを開始したスレッドである必要はなく、トランザクションを処理しているどのスレッドでもかまいません。スレッド アプリケーションでは、通常のトランザクション規則に従うために、適切に同期を行う必要があります。たとえば、未終了の RPC 呼び出しや会話がある場合に、トランザクションをコミットすることはできません。また、トランザクションがコミットまたはアボートされた後で、そのトランザクションに対する呼び出しを行うことはできません。プロセスは、アプリケーションの各対応付けに対して、1 つのトランザクションの一部にだけなることができます。

アプリケーションの 1 つのスレッドが tpcommit(3c) を呼び出し、それと同時に別のスレッドが RPC 呼び出しまたは会話型呼び出しを行うと、これらの呼び出しは特定の順序で呼び出されたものとして処理されます。アプリケーション コンテキストは、シングルスレッド プログラムとシングルコンテキスト プログラムに対する制約と同じ制約に従って、tpsuspend(3c) を呼び出してトランザクションを一時的に中断し、別のトランザクションを開始します。

非請求メッセージ

マルチスレッド アプリケーションまたはマルチコンテキスト アプリケーションの各コンテキストでは、非請求メッセージを次の 3 種類のいずれかの方法で処理できます。

処理方法
設定
非請求メッセージの無視
TPU_IGN
ディップ イン通知
TPU_DIP
専用のスレッド通知
(C 言語のアプリケーションのみで利用可能です)
TPU_THREAD

以下の事柄に注意してください。

専用のスレッド通知の場合、非請求メッセージの受信と、非請求メッセージ ハンドラのディスパッチに別々のスレッドが使用されます。あるコンテキストで一度に実行できる非請求メッセージ ハンドラは 1 つだけです。

スレッドがサポートされていない Oracle Tuxedo システム用プラットフォームで tpinit(3c) が呼び出された場合に、スレッドがサポートされていないプラットフォーム上で TPU_THREAD 通知が要求されたことを示すパラメータが指定されていると、tpinit()-1 を返して tperrnoTPEINVAL を設定します。UBBCONFIG(5) のデフォルトの NOTIFY オプションが THREAD に設定されている場合に、特定のマシンでスレッドを利用できないと、そのマシンのデフォルトの機能は DIPIN になります。このような動作の相違があるので、スレッドがサポートされているマシンとサポートされていないマシンが混在する環境では、管理者はすべてのマシンにデフォルトを指定できます。ただし、そのマシンで利用できない機能をクライアントが明示的に要求することはできません。

tpsetunsol(3c) がコンテキストに対応付けされていないスレッドから呼び出されると、新しく生成されるすべての tpinit(3c) コンテキストに対して、プロセス単位のデフォルトの非請求メッセージ ハンドラが作成されます。特定のコンテキストは、コンテキストがアクティブのときに tpsetunsol() を再度呼び出して、そのコンテキストの非請求メッセージ ハンドラを変更することができます。プロセス単位のデフォルトの非請求メッセージ ハンドラは、コンテキストに現在対応付けされていないスレッドで tpsetunsol() を再度呼び出すと、変更できます。

プロセスが同じアプリケーションと複数の対応付けを持つ場合、各対応付けに異なる CLIENTID を割り当てられ、非請求メッセージを特定のアプリケーションとの対応付けに送信できるようになります。プロセスが同じアプリケーションと複数の対応付けを持つ場合、ブロードキャスト基準を満たすアプリケーションの各対応付けに任意の tpbroadcast(3c) が別々に送信されます。非請求メッセージを受信する場合のディップ イン チェックでは、カレントのアプリケーションとの対応付けに送信されるメッセージだけが対象となります。

非請求メッセージ ハンドラでは ATMI 関数を利用できるほか、非請求メッセージ ハンドラ内で tpgetctxt(3c) を呼び出すことができます。そのため、非請求メッセージ ハンドラは別のスレッドを生成して、同じコンテキスト内で必要となる実質的な ATMI 作業を行うことができるようになります。

ユーザ ログで保持されるスレッド固有の情報

userlog(3c) を使用すると、各アプリケーション内の各スレッドに対して次の識別情報が記録されます。

process_ID.thread_ID.context_ID

スレッドがサポートされていないプラットフォームやシングルコンテキスト アプリケーションに対しては、thread_ID フィールドと context_ID フィールドにプレースホルダが出力されます。

TM_MIB(5) では、この機能は T_ULOG クラスの TA_THREADID フィールドと TA_CONTEXTID フィールドでサポートされています。

完了フェーズ

このフェーズでは、クライアント プロセスの終了時に、現在のコンテキストおよび対応付けられたすべてのスレッドに代わって 1 つのスレッドが tpterm(3c) を呼び出してそのアプリケーションとの対応付けを終了します。ほかの ATMI 関数と同じように、tpterm() は現在のコンテキストに対して処理を行います。tpterm() は、終了するコンテキストに対応付けされたすべてのスレッドに影響し、これらのスレッドで共有されるすべてのコンテキストを終了します。

アプリケーションの設計が適切であれば、特定のコンテキスト内のすべての処理が完了してから tpterm() が呼び出されます。tpterm() が呼び出される前に、すべてのスレッドが同期していなければなりません。

関連項目

 


サーバでのマルチスレッドとマルチコンテキストの動作

マルチスレッドおよびマルチコンテキスト アプリケーションがアクティブの場合、サーバで行われる処理は次の 3 つのフェーズに分類できます。

起動フェーズ

起動フェーズで行われる処理は、コンフィグレーション ファイルの MINDISPATCHTHREADSMAXDISPATCHTHREADS パラメータの値によって異なります。

MINDISPATCHTHREADS の値
MAXDISPATCHTHREADS の値
結果
0
> 1
  1. Oracle Tuxedo システムがスレッド ディスパッチャを生成します。
  2. ディスパッチャが tpsvrinit(3c) を呼び出して、アプリケーションに参加します。
> 0
> 1
  1. Oracle Tuxedo システムがスレッド ディスパッチャを生成します。
  2. ディスパッチャが tpsvrinit(3c) を呼び出して、アプリケーションに参加します。
  3. Oracle Tuxedo システムがサービス要求を処理する新しいスレッドと、そのスレッドに対するコンテキストを生成します。
  4. システムで生成された新しいスレッドがそれぞれ tpsvrthrinit(3c) を呼び出して、アプリケーションに参加します。

作業フェーズ

このフェーズでは、次の処理が行われます。

サーバ ディスパッチ スレッド

クライアントのサービス要求への応答として、サーバ ディスパッチャは設定可能な最大数まで複数のスレッドを 1 つのサーバに生成します。このサーバは、各種のクライアント要求に同時に割り当てることができます。サーバが tpinit(3c) を呼び出してクライアントになることはできません。

各ディスパッチ スレッドは、別々のコンテキストと対応付けられています。この機能は会話型サーバと RPC サーバで有用です。特に、会話型サーバではこの機能を利用できないと、ほかの会話接続がサービスを待っている間、クライアントサイドの会話をアイドル状態で待つことになります。

この機能は、UBBCONFIG(5) ファイルの SERVERS セクションと TM_MIB(5) の次のパラメータで制御されます。

UBBCONFIG パラメータ
MIB パラメータ
デフォルト値
MINDISPATCHTHREADS
TA_MINDISPATCHTHREADS
0
MAXDISPATCHTHREADS
TA_MAXDISPATCHTHREADS
1
THREADSTACKSIZE
TA_THREADSTACKSIZE
0 (オペレーティング システムのデフォルト値)

アプリケーション生成のスレッド

オペレーティング システム関数を使用して、アプリケーション サーバ内に新しいスレッドを追加できます。アプリケーション生成のスレッドは、次のように動作します。

アプリケーション内にスレッドを生成する場合、次の制約があります。

BBL によるシステム プロセスの正常性チェック

BBL は定期的にサーバを検証します。特定のサービス要求の実行に時間がかかりすぎている場合、BBL はそのサーバを強制終了します。そして、指定されている場合は、そのサーバを再起動します。BBL がマルチコンテキスト サーバを強制終了した場合、プロセスを強制終了した結果として、実行中のそのほかのサービス呼び出しも終了します。

また、BBL はタイムアウト値を超えてメッセージの受信を待機しているプロセスまたはスレッドにメッセージを送信します。すると、ブロッキング メッセージ受信への呼び出しが、タイムアウトを示すエラーを返します。

システムで保持されるサーバ スレッドの統計

Oracle Tuxedo システムでは、各サーバに対して次の統計情報が保持されます。

ユーザ ログで保持されるスレッド固有の情報

userlog(3c) を使用すると、各アプリケーション内の各スレッドに対して次の識別情報が記録されます。

process_ID.thread_ID.context_ID

スレッドがサポートされていないプラットフォームやシングルコンテキスト アプリケーションに対しては、thread_ID フィールドと context_ID フィールドにプレースホルダが出力されます。

TM_MIB(5) では、この機能は T_ULOG クラスの TA_THREADID フィールドと TA_CONTEXTID フィールドでサポートされています。

完了フェーズ

アプリケーションを停止すると、tpsvrthrdone(3c)tpsvrdone(3c) が呼び出されて、リソース マネージャのクローズなど、必要な終了処理が行われます。

関連項目

 


マルチスレッドおよびマルチコンテキスト アプリケーションの設計上の検討事項

マルチスレッドおよびマルチコンテキスト アプリケーションは、一部の Oracle Tuxedo ドメインでは正しく動作しますが、すべてのドメインで正しく動作するとは限りません。そのようなアプリケーションを作成するかどうかは、次の基本事項を検討してから決定します。

環境の要件

マルチスレッド アプリケーションまたはマルチコンテキスト アプリケーションの開発では、開発環境と実行時環境に関して次の内容を検討します。

設計の要件

マルチスレッド アプリケーションやマルチコンテキスト アプリケーションの設計では、次の内容を検討します。

マルチスレッドやマルチコンテキストに適するアプリケーションのタスク

次の表は、アプリケーションをマルチスレッドまたはマルチコンテキストにすべきかどうかを判断するための参考となる検討事項を示しています。この表だけでは十分ではないので、個々の要件に基づいてほかの事項も検討してください。

そのほかの検討事項については、マルチスレッド アプリケーションやマルチコンテキスト アプリケーションのプログラミングに関する書籍を参照してください。

検討事項
検討事項に該当する場合に使用する機能
ドメイン機能を使用せずに、クライアントが複数のアプリケーションに接続する必要があるか
マルチコンテキスト。
アプリケーション内でクライアントが多重化の機能を果たすか。たとえば、アプリケーション内の 1 つのマシンがそのほかの 100 台のマシンの「代理」に指定されているか
マルチコンテキスト。
クライアントでマルチコンテキストが使用されるか
マルチスレッド。各コンテキストにスレッドを 1 つずつ割り当てると、コードを簡略化できます。
クライアントが 2 つ以上のタスクを長時間個別に実行することで、並列処理によるパフォーマンスがスレッド同期のコストと複雑さを上回るか
マルチスレッド。
1 つのサーバで複数の要求を同時に処理するか
マルチスレッド。MAXDISPATCHTHREADS に 1 より大きな値を割り当てます。このように設定すると、1 つのサーバで複数のクライアントをそのクライアントのスレッドで処理できるようになります。
クライアントまたはサーバに複数のスレッドがある場合、各スレッドでわずかな処理を行った後でもスレッドを同期する必要があるか
マルチスレッドを使用しません。

必要なアプリケーションと接続の数

アクセスするアプリケーションの数と、確立する接続の数を決定します。

同期に関する検討事項

これは設計段階での重要な検討事項です。このマニュアルでは、この内容について取り上げていません。マルチスレッド アプリケーションやマルチコンテキスト アプリケーションのプログラミングに関する書籍を参照してください。

アプリケーションの移植

後でアプリケーションを移植する必要がある場合、オペレーティング システムに応じて異なる関数が使用されていることに注目してください。あるプラットフォームで作成した初期バージョンのアプリケーションを後で移植する場合、異なる関数でコードを書き直すためにどれだけのリソース時間が必要なのかを考慮する必要があります。

最適なスレッド モデル

現在使用されているマルチスレッド プログラムには、次のようなモデルがあります。

スレッド モデルについては、このマニュアルでは取り上げていません。アプリケーションのプログラミング モデルを選択する場合は、利用できるすべてのモデルを調べて、設計の要件を慎重に検討してください。

ワークステーション クライアントの相互運用性に関する制約

リリース 7.1 の Workstation クライアントと 7.1 以前の Oracle Tuxedo システムに基づくアプリケーションとの相互運用性は、次のどの場合でもサポートされています。

Oracle Tuxedo リリース 7.1 のワークステーション クライアントで、1 つのコンテキストに複数のスレッドがある場合は、リリース 7.1 より前の Oracle Tuxedo システムとは相互運用しません。

関連項目

 


マルチスレッドおよびマルチコンテキスト アプリケーションの実装

 


マルチスレッドおよびマルチコンテキスト アプリケーションのプログラミング開始前のガイドライン

コーディングを開始する前に、次の内容や条件を満たしていることを確認してください。

マルチスレッド アプリケーションに必要な条件

開発プロジェクトを開始する前に、開発環境が次の条件を満たしていることを確認します。

マルチスレッド アプリケーションのプログラミングでの一般的な検討事項

マルチスレッド プログラムは、十分に経験を持つプログラマがコーディングします。特に、次のようなマルチスレッド固有の設計に関する基本的な知識があることが必要です。

これらは検討事項の一部にすぎず、ここに記せないほど多くの検討事項があります。マルチスレッド プログラムをコーディングするプログラマは、それらの検討事項を熟知していることが前提となります。これらの検討事項については、マルチスレッド アプリケーションのプログラミングに関する書籍を参照してください。

並列性に関する検討事項

マルチスレッドを使用すると、1 つのアプリケーションの異なるスレッドが同じ会話で並列処理を行うことができるようになります。この方法はお勧めしませんが、Oracle Tuxedo システムで禁止されているわけではありません。異なるスレッドによって同じ会話で並列処理が行われると、システムは同時呼び出しが任意の順序で行われたように動作します。

複数のスレッドを使ってプログラミングする場合、ミューテックスなどの同時実行制御関数を使用して、スレッド間の並列処理を管理する必要があります。以下は、同時実行制御が必要になる 3 つの例です。

関連項目

 


クライアントでマルチコンテキストを使用するためのコーディング

クライアントでマルチコンテキストを使用するには、次の内容をコーディングします。

アプリケーションでトランザクションを使用する場合、トランザクションのマルチコンテキストの結果についても注目します。詳細については、「マルチスレッドおよびマルチコンテキスト アプリケーションにおけるトランザクションのコーディング規則」を参照してください。

注意 : この節で示す手順とサンプル コードは、Oracle Tuxedo システムで提供される C 言語のライブラリ関数を参照します。それらに相当する COBOL ライブラリ関数も利用できます。詳細については、『Tuxedo COBOL リファレンス』を参照してください。

コンテキストの属性

コンテキストを使用する場合、コーディングで以下の事柄に注意してください。

初期化時のマルチコンテキストの設定

クライアントがアプリケーションに参加する準備ができたら、次のサンプル コードに示すように、TPMULTICONTEXTS フラグを設定して tpiit(3c) を指定します。

コード リスト 10-1 クライアントのマルチコンテキスト アプリケーションへの参加
#include <stdio.h>
#include <atmi.h>

TPINIT * tpinitbuf;

main()
{
tpinitbuf = tpalloc(TPINIT, NULL, TPINITNEED(0));

tpinitbuf->flags = TPMULTICONTEXTS;
.
.
.
if (tpinit (tpinitbuf) == -1) {
    		ERROR_PROCESSING_CODE
}
.
.
.
}

新しいアプリケーションとの対応付けが生成され、TUXCONFIG または WSENVFILE/WSNADDR 環境変数で指定された Oracle Tuxedo ドメインに割り当てられます。

注意 : 1 つのプロセスでは、tpinit(3c) へのすべての呼び出しに TPMULTICONTEXTS フラグを含めます。または、tpinit() へのすべての呼び出しにこのフラグを含めません。この規則には、例外が 1 つあります。つまり、tpterm(3c) への呼び出しが正常に終了して、クライアントのすべてのアプリケーション対応付けが終了した場合、次に tpinit() を呼び出すときに必ずしも TPMULTICONTEXTS フラグを含む必要のない状態にプロセスが復元されます。

マルチコンテキスト クライアントのセキュリティの実装

同じプロセス内の各アプリケーションとの対応付けには、別個にセキュリティ検査を行う必要があります。検査の内容は、アプリケーションで使用されているセキュリティ メカニズムのタイプによって異なります。たとえば、Oracle Tuxedo アプリケーションでは、システム レベルのパスワードまたはアプリケーション パスワードを使用します。

マルチコンテキスト アプリケーションのプログラマは、アプリケーションで使用するセキュリティのタイプを決定し、そのセキュリティをプロセス内の各アプリケーションとの対応付けに実装します。

クライアント終了前のスレッドの同期

クライアントをアプリケーションから切断する準備ができたら、tpterm(3c) を呼び出します。ただし、マルチコンテキスト アプリケーションでは、tpterm() を呼び出すと現在のコンテキストが破棄されることに注目してください。その場合、現在のコンテキストで動作しているすべてのスレッドが影響を受けます。アプリケーション プログラマは、tpterm() が不意に呼び出されることがないように、複数のスレッドを使用する場合は注意してください。

まだ処理を行っているスレッドがあるコンテキストでは、tpterm(3c) を呼び出さないようにします。そのような状況で tpterm() を呼び出すと、そのコンテキストと対応付けられていたほかのスレッドが特別な無効コンテキスト状態になります。無効コンテキスト状態では、大部分の ATMI 関数を使用できなくなります。無効コンテキスト状態からスレッドを解放するには、tpsetctxt(3c) または tpterm() を呼び出します。良く設計されたアプリケーションでは、無効コンテキスト状態が生じることはありません。

注意 : Oracle Tuxedo システムでは、COBOL アプリケーションのマルチスレッドはサポートされていません。

コンテキストの切り替え

次は、2 つのコンテキストからサービスを呼び出すクライアントで行われる処理の手順をまとめたものです。

  1. TUXCONFIG 環境変数に firstapp で必要な値を設定します。
  2. TPMULTICONTEXTS フラグを設定して tpinit(3c) を呼び出し、最初のアプリケーションに参加します。
  3. tpgetctxt(3c) を呼び出して、現在のコンテキストへのハンドルを取得します。
  4. tuxputenv() を呼び出して、TUXCONFIG 環境変数の値を secondapp コンテキストに必要な値に切り替えます。
  5. TPMULTICONTEXTS フラグを設定して tpinit(3c) を呼び出して、2 番目のアプリケーションに参加します。
  6. tpgetctxt(3c) を呼び出して、現在のコンテキストへのハンドルを取得します。
  7. tpsetctxt(3c) を呼び出して、firstapp コンテキストからコンテキストの切り替えを開始します。
  8. firstapp サービスを呼び出します。
  9. tpsetctxt(3c) を呼び出してクライアントを secondapp コンテキストに切り替え、secondapp サービスを呼び出します。
  10. tpsetctxt(3c) を呼び出してクライアントを firstapp コンテキストに切り替え、firstapp サービスを呼び出します。
  11. tpterm(3c) を呼び出して、firstapp コンテキストを終了します。
  12. tpsetctxt(3c) を呼び出してクライアントを secondapp コンテキストに切り替え、secondapp サービスを呼び出します。
  13. tpterm(3c) を呼び出して、secondapp コンテキストを終了します。

次のサンプル コードは、この手順を示しています。

注意 : コードを簡単にするために、エラー チェックは省略してあります。
コード リスト 10-2 クライアントでのコンテキストの切り替え
#include <stdio.h>
#include "atmi.h" /* BEA Tuxedo ヘッダ ファイル */

#if defined(__STDC__) || defined(__cplusplus)
main(int argc, char *argv[])
#else
main(argc, argv)
int argc;
char *argv[];
#endif
{

TPINIT * tpinitbuf;
TPCONTEXT_T firstapp_contextID, secondapp_contextID;
/* TUXCONFIG が /home/firstapp/TUXCONFIG に設定されていることを前提とする */
/*
* BEA Tuxedo システムにマルチコンテキスト モードで接続 */

tpinitbuf=tpalloc(TPINIT, NULL, TPINITNEED(0));
tpinitbuf->flags = TPMULTICONTEXTS;

if (tpinit((TPINIT *) tpinitbuf) == -1) {
(void) fprintf(stderr, "Tpinit failed\n");
exit(1);
}

/*
* 現在のコンテキストへのハンドルを取得
*/
tpgetctxt(&firstapp_contextID, 0);

/*
* tuxputenv を使用して TUXCONFIG の値を変更し、
* 別のアプリケーションに参加 (tpinit)
*/ */
tuxputenv("TUXCONFIG=/home/second_app/TUXCONFIG");

/*
* secondapp に参加 (tpinit)
*/
if (tpinit((TPINIT *) tpinitbuf) == -1) {
(void) fprintf(stderr, "Tpinit failed\n");
exit(1);
}

/*
* secondapp のコンテキストへのハンドルを取得
*/
tpgetctxt(&secondapp_contextID, 0);

/*
* tpgetctxt から取得したハンドルと tpsetctxt を使用して、
* 2 つのコンテキスト間で切り替えが
* できる。firstapp から開始
*/

tpsetctxt(firstapp_contextID, 0);

/*
* firstapp で提供されるサービスを呼び出し、
* 次に secondapp に切り替える
*/

tpsetctxt(secondapp_contextID, 0);

/*
* secondapp で提供されるサービスを呼び出す
* 次に firstapp に戻る
*/

tpsetctxt(firstapp_contextID, 0);

/*
* firstapp で提供されるサービスを呼び出す。操作が終了したら
* firstapp のコンテキストを終了
*/

tpterm();

/*
* secondapp に戻る
*/

tpsetctxt(secondapp_contextID, 0);
/*
* secondapp で提供されるサービスを呼び出す。操作が終了したら
* secondapp のコンテキストを終了し、
* プログラムを終了
*/

tpterm();

return(0);
}

非請求メッセージの処理

非請求メッセージを処理する各コンテキストでは、非請求メッセージ ハンドラを設定するか、またはプロセス ハンドラのデフォルトが設定されている場合はそれを使用する必要があります。

tpsetunsol(3c) がコンテキストに対応付けされていないスレッドから呼び出されると、新しく生成されるすべての tpinit(3c) コンテキストに対して、プロセス単位のデフォルトの非請求メッセージ ハンドラが作成されます。特定のコンテキストは、コンテキストがアクティブのときに tpsetunsol() を再度呼び出して、そのコンテキストの非請求メッセージ ハンドラを変更することができます。プロセス単位のデフォルトの非請求メッセージ ハンドラは、コンテキストに現在対応付けされていないスレッドで tpsetunsol() を再度呼び出すと、変更できます。

ハンドラの設定は、シングルスレッド アプリケーションまたはシングルコンテキスト アプリケーションのハンドラを設定する場合と同じように行います。詳細については、tpsetunsol(3c) を参照してください。

現在処理を行っているコンテキストを識別するには、非請求メッセージ ハンドラ内で tpgetctxt(3c) を使用します。

マルチスレッドおよびマルチコンテキスト アプリケーションにおけるトランザクションのコーディング規則

トランザクションを使用する場合、コーディングで以下の事柄に注意してください。

関連項目

 


サーバでマルチコンテキストとマルチスレッドを使用するためのコーディング

ここでは、以下の内容について説明します。

注意 : この節で示す手順とサンプル コードは、Oracle Tuxedo システムで提供される C 言語のライブラリ関数を参照します。詳細については、『Oracle Tuxedo C リファレンス』を参照してください。COBOL アプリケーションではマルチコンテキスト サーバの生成に必要なマルチスレッドがサポートされていないので、C 言語の関数に相当する COBOL ルーチンは利用できません。

コンテキストの属性

コンテキストを使用する場合、コーディングで以下の事柄に注意してください。

マルチコンテキスト サーバのコーディング規則

マルチコンテキスト サーバ使用する場合、コーディングで以下の規則に注意してください。

サーバおよびサーバ スレッドの初期化と終了

サーバとサーバ スレッドの初期化と終了には、Oracle Tuxedo システムで提供されるデフォルトの関数や独自の関数を使用できます。

表 10-1 初期化と終了を行うデフォルトの関数
目的
使用するデフォルトの関数
サーバの初期化
サーバ スレッドの初期化
サーバの終了
サーバ スレッドの終了

スレッドを生成するためのサーバのプログラミング

マルチコンテキスト サーバを使用するほとんどのアプリケーションでは、システム生成のディスパッチ サーバ スレッドだけが使用されます。ただし、アプリケーション サーバに新しいスレッドを生成することもできます。この節では、その方法について説明します。

スレッドの生成

オペレーティング システムのスレッド関数を使用して、アプリケーション サーバに新しいスレッドを生成できます。これらの新しいスレッドは、Oracle Tuxedo システムから独立して動作できます。また、いずれかのサーバ ディスパッチ スレッドと同じコンテキストで動作することもできます。

コンテキストへのスレッドの対応付け

アプリケーション生成のサーバ スレッドは、当初どのサーバ ディスパッチ コンテキストにも対応付けられていません。ただし、初期化される前に呼び出された場合、ほとんどの ATMI 関数は暗黙的に tpinit(3c) を実行します。サーバで tpinit() を呼び出すことは禁止されているので、そのような呼び出しを行うと問題が発生します。サーバ プロセスが tpinit() を呼び出すと、tpinit() は -1 を返して tperrno(5)TPEPROTO を設定します。

そのため、アプリケーション生成のサーバ スレッドは、既存のコンテキストと対応付けを行ってから ATMI 関数を呼び出す必要があります。アプリケーション生成のサーバ スレッドを既存のコンテキストに対応付けるには、以下の手順をコーディングします。

  1. サーバ ディスパッチ スレッド_A は、tpgetctxt(3c) を呼び出して現在のコンテキストへのハンドルを取得します。
  2. サーバ ディスパッチ スレッド_A は、tpgetctxt(3c) が返すハンドルをアプリケーション スレッド_B に渡します。
  3. アプリケーション スレッド_B は、tpsetctxt(3c) を呼び出してサーバ ディスパッチ スレッド_A から受け取ったハンドルを指定して、現在のコンテキストとの対応付けを作成します。
  4. アプリケーション生成のサーバ スレッドは、tpreturn(3c) または tpforward(3c) を呼び出すことはできません。元のディスパッチ スレッドが tpreturn() または tpforward() を呼び出す前に、そのコンテキストにあったすべてのアプリケーション生成のサーバ スレッドは TPNULLCONTEXT または別の有効なコンテキストに切り替える必要があります。
  5. この規則に違反すると、tpforward(3c) または tpreturn(3c) が失敗し、呼び出し側にサービス エラーが示されます。

マルチコンテキスト サーバでアプリケーション スレッドを生成するためのサンプル コード

次のサンプル コードは、サービスが別のスレッドを生成してそのサービスの作業を行うマルチコンテキスト サーバを示しています。このコードは、サーバでアプリケーション スレッドを生成する必要があるアプリケーションで使用します。オペレーティング システムのスレッド関数は、オペレーティング システムによって異なります。このサンプル コードでは、POSIX 関数と ATMI 関数が使用されています。

注意: コードを簡単にするために、エラー チェックは省略してあります。また、Oracle Tuxedo システムによってディスパッチされたスレッドだけを使用するマルチコンテキスト サーバも省略してあります。そのようなサーバのコーディングは、スレッド セーフのプログラミング方法が使用されている場合、シングルコンテキスト サーバのコーディングとまったく同じです。
コード リスト 10-3 マルチコンテキスト サーバでのスレッドの生成
#include <pthread.h>
#include <atmi.h>

void *withdrawalthread(void *);

struct sdata {
TPCONTEXT_T ctxt;
TPSVCINFO *svcinfoptr;
};

void
TRANSFER(TPSVCINFO *svcinfo)
{
struct sdata transferdata;
pthread_t withdrawalthreadid;

tpgetctxt(&transferdata.ctxt, 0);
transferdata.svcinfoptr = svcinfo;
pthread_create(&withdrawalthreadid, NULL, withdrawalthread, &transferdata);
tpcall("DEPOSIT", ...);
pthread_join(withdrawalthreadid, NULL);
tpreturn(TPSUCCESS, ...);
}


void *
withdrawalthread(void *arg)
{
tpsetctxt(arg->ctxt, 0);
tpopen();
tpcall("WITHDRAWAL", ...);
tpclose();
return(NULL);
}

このコードでは、元のディスパッチ スレッドで DEPOSIT サービスを呼び出し、アプリケーション生成のスレッドで WITHDRAWAL を呼び出して、口座振り替えを行っています。この例では、リソース マネージャで混在モデルがサポートされていることを前提としています。つまり、サーバのすべてのスレッドが特定のインスタンスと対応付けされていなくても、そのサーバの複数のスレッドが特定のデータベース接続と対応付けられます。ただし、そのようなモデルがサポートされたリソース マネージャはほとんどありません。

アプリケーション生成のスレッドを使用しないようにすると、このコードはさらに簡単になります。このサンプル コードで tpcall(3c) を 2 回呼び出して行っている並列処理を実現するには、サーバ ディスパッチ スレッド内で tpacall(3c)tpgetrply(3c) をそれぞれ 2 回呼び出します。

関連項目

 


マルチスレッド クライアントのコーディング

ここでは、以下の内容について説明します。

注意 : Oracle Tuxedo システムでは、COBOL アプリケーションのマルチスレッドはサポートされていません。

マルチスレッド クライアントのコーディング規則

マルチスレッド クライアントを使用する場合、コーディングで以下の規則に注意してください。

クライアントの複数のコンテキストへの初期化

クライアントを複数のコンテキストに参加させるには、TPINIT データ構造体の flags 要素に TPMULTICONTEXTS フラグを設定して tpinit(3c) 関数を呼び出します。

1 つのプロセスでは、tpinit(3c) へのすべての呼び出しに TPMULTICONTEXTS フラグを含めます。または、tpinit() へのすべての呼び出しにこのフラグを含めません。この規則には、例外が 1 つあります。つまり、tpterm(3c) への呼び出しが正常に終了して、クライアントのすべてのアプリケーション対応付けが終了した場合、次に tpinit() を呼び出すときに必ずしも TPMULTICONTEXTS フラグを含む必要のない状態にプロセスが復元されます。

TPMULTICONTEXTS フラグを設定して tpinit(3c) 関数が呼び出されると、アプリケーションとの新しい対応付けが生成され、スレッドに対するカレントの対応付けが設定されます。新しい対応付けが生成される Oracle Tuxedo ドメインは、TUXCONFIG または WSENVFILE/WSNADDR 環境変数の値で決定されます。

クライアント スレッドが TPMULTICONTEXTS フラグを設定せずに tpinit(3c) を正常に実行した場合、クライアントのすべてのスレッドがシングルコンテキスト状態 (TPSINGLECONTEXT) になります。

tpinit(3c) が失敗した場合、呼び出し側スレッドは元のコンテキスト、つまり tpinit() 呼び出しの前に操作していたコンテキスト状態のままになります。

まだ動作中のスレッドがあるコンテキストから tpterm(3c) を呼び出すことはできません。このような状況やそれ以外の状況で tpterm() を呼び出した結果生じるコンテキスト状態については、「マルチコンテキスト状態の遷移」を参照してください。

クライアント スレッドのコンテキスト状態の変化

マルチコンテキストのアプリケーションでは、いろいろな関数を呼び出すと、呼び出し側スレッド、および呼び出し側プロセスと同じコンテキストでアクティブなその他のスレッドのコンテキスト状態が変化します。次の図は、tpinit(3c)tpsetctxt(3c)、および tpterm(3c) を呼び出した結果、変化したコンテキスト状態を示しています。tpgetctxt(3c) 関数を呼び出しても、コンテキスト状態は変化しません。

図 10-4 マルチコンテキスト状態の遷移

マルチコンテキスト状態の遷移

注意 : tpterm(3c) がマルチコンテキスト状態 (TPMULTICONTEXTS) で実行しているスレッドによって呼び出されると、呼び出し側スレッドは NULL コンテキスト状態 (TPNULLCONTEXT) になります。終了するコンテキストに関連するその他すべてのスレッドは、無効コンテキスト状態 (TPINVALIDCONTEXT) に切り替わります。

次の表は、tpinit(3c)tpsetctxt(3c)、および tpterm(3c) を呼び出した場合のコンテキスト状態の変化を示しています。

表 10-2 クライアント スレッドのコンテキスト状態の変化
実行する関数
実行後のスレッドのコンテキスト状態
NULL コンテキスト
シングルコンテキスト
マルチコンテキスト
無効コンテキスト
TPMULTICONTEXTS が設定されていない tpinit(3c)
シングルコンテキスト
シングルコンテキスト
エラー
エラー
TPMULTICONTEXTS が設定された tpinit(3c)
マルチコンテキスト
エラー
マルチコンテキスト
エラー
TPNULLCONTEXT への tpsetctxt(3c)
NULL
エラー
NULL
NULL
コンテキスト 0 への tpsetctxt(3c)
エラー
シングルコンテキスト
エラー
エラー
コンテキスト > 0 への tpsetctxt(3c)
マルチコンテキスト
エラー
マルチコンテキスト
マルチコンテキスト
暗黙の tpinit(3c)
シングルコンテキスト
該当なし
該当なし
エラー
このスレッドでの tpterm(3c)
NULL
NULL
NULL
NULL
このコンテキストの異なるスレッドでの tpterm(3c)
該当なし
NULL
無効
該当なし

マルチスレッド環境での応答の取得

tpgetrply(3c) は、tpacall(3c) からの要求に対する応答だけを受け取ります。tpcall(3c) からの要求は、マルチスレッドまたはマルチコンテキストのレベルに関係なく、tpgetrply() で取得することはできません。

tpgetrply(3c) は、1 つのコンテキスト、つまり呼び出し側コンテキストだけで動作します。そのため、TPGETANY フラグを設定して tpgetrply() を呼び出すと、同じコンテキストで生成されたハンドルだけが考慮されます。同じように、あるコンテキストで生成されたハンドルを別のコンテキストで使用することはできません。ただし、同じコンテキストで動作するスレッドには、そのハンドルを使用できます。

tpgetrply(3c) をマルチスレッド環境で呼び出す場合、以下の制約があります。

マルチスレッド マルチコンテキスト環境の環境変数

Oracle Tuxedo アプリケーションをマルチコンテキスト マルチスレッド環境で実行する場合、環境変数に関して以下の事柄に注意してください。

マルチスレッド クライアントでのコンテキスト単位の関数とデータ構造体

以下に示す ATMI 関数は、呼び出し側のアプリケーション コンテキストだけに影響します。

注意 : tpbroadcast(3c) の場合、ブロードキャスト メッセージは特定のアプリケーションとの対応付けから送られたものとして識別されます。tpnotify(3c) の場合、通知は特定のアプリケーションとの対応付けから送られたものとして識別されます。tpinit(3c) の注記については、「マルチスレッド クライアントでのプロセス単位の関数とデータ構造体」を参照してください。
注意 : tpsetunsol(3c) がコンテキストに対応付けされていないスレッドから呼び出されると、新しく生成されるすべての tpinit(3c) コンテキストに対して、プロセス単位のデフォルトの非請求メッセージ ハンドラが作成されます。特定のコンテキストは、コンテキストがアクティブのときに tpsetunsol() を再度呼び出して、そのコンテキストの非請求メッセージ ハンドラを変更することができます。プロセス単位のデフォルトの非請求メッセージ ハンドラは、コンテキストに現在対応付けされていないスレッドで tpsetunsol() を再度呼び出すと、変更できます。

マルチスレッド クライアントでのプロセス単位の関数とデータ構造体

以下に示す Oracle Tuxedo 関数は、呼び出し側のプロセス全体に影響します。

シングルコンテキスト モード、マルチコンテキスト モード、または非初期化モードのどれを使用するかは、プロセス全体に影響します。また、バッファ タイプ スイッチ、ビュー キャッシュ、および環境変数の値も、プロセス単位の関数です。

マルチスレッド クライアントでのスレッド単位の関数とデータ構造体

以下に示す関数は、呼び出し側のスレッドだけに影響します。

Ferror、Ferror32(5)tperrno(5)tpurcode(5)、および Uunix_err 変数は、各スレッドに固有です。

現在のコンテキストの ID は各スレッドに固有です。

マルチスレッド クライアントのサンプル コード

次のサンプル コードは、ATMI 呼び出しを使用するマルチスレッド クライアントを示しています。スレッド関数は、オペレーティング システムによって異なります。この例では、POSIX 関数が使用されています。

注意 : コードを簡単にするために、エラー チェックは省略してあります。
コード リスト 10-4 マルチスレッド クライアントのサンプル コード
#include <stdio.h>
#include <pthread.h>
#include <atmi.h>

TPINIT * tpinitbuf;
int timeout=60;
pthread_t withdrawalthreadid, stockthreadid;
TPCONTEXT_T ctxt;
void * stackthread(void *);
void * withdrawalthread(void *);

main()
{
tpinitbuf = tpalloc(TPINIT, NULL, TPINITNEED(0));
/*
* このコードでは、withdrawal スレッドと deposit スレッドという別のスレッドを
* 使用して振り込みを行う。また、BEA 株の現在の価格を
* 別のアプリケーションから取得し、送金した金額で
* 購入できる株数を計算する
*/

tpinitbuf->flags = TPMULTICONTEXTS;

/* 残りの tpinitbuf を設定 */
tpinit(tpinitbuf);

tpgetctxt(&ctxt, 0);
tpbegin(timeout, 0);
pthread_create(&withdrawalthreadid, NULL, withdrawalthread, NULL);
tpcall("DEPOSIT", ...);

/* withdrawal スレッドの完了を待機 */
pthread_join(withdrawalthreadid, NULL);

tpcommit(0);
tpterm();

/* stock スレッドの完了を待機 */
pthread_join(stockthreadid, NULL);

/* 結果を出力 */
printf("$%9.2f has been transferred \
from your savings account to your checking account.\n", ...);

printf("At the current BEA stock price of $%8.3f, \
you could purchase %d shares.\n", ...);

exit(0);
}



void *
stockthread(void *arg)
{

/* ほかのスレッドが tpinit() を呼び出しているので、
* TUXCONFIG を再設定してもスレッドに影響しない
*/

tuxputenv("TUXCONFIG=/home/users/xyz/stockconf");
tpinitbuf->flags = TPMULTICONTEXTS;
/* 残りの tpinitbuf を設定 */
tpinit(tpinitbuf);
tpcall("GETSTOCKPRICE", ...);
/* main() でもアクセスできる変数に株価を格納 */
tpterm();
return(NULL);
}



void *
withdrawalthread(void *arg)
{
/* 別のアプリケーションから株価を取得するために新しいスレッドを
* 生成
*/


pthread_create(&stockthreadid, NULL, stockthread, NULL);
tpsetctxt(ctxt, 0);
tpcall("WITHDRAWAL", ...);
return(NULL);
}

関連項目

 


マルチスレッド サーバのコーディング

ほとんどの場合、マルチスレッド サーバはマルチコンテキストでもあります。マルチスレッド サーバのコーディングについては、「サーバでマルチコンテキストとマルチスレッドを使用するためのコーディング」を参照してください。

 


マルチスレッドおよびマルチコンテキスト アプリケーションのコードのコンパイル

buildserver(1)buildclient(1) など、コンパイルまたはビルドの実行可能ファイル用に Oracle Tuxedo システムで提供されるプログラムには、必要なコンパイラ フラグが自動的に設定されます。これらのツールを使用すると、コンパイル時にフラグを設定する必要がありません。

ただし、最終的なコンパイルの前に .c ファイルを .o ファイルにコンパイルする場合は、プラットフォーム固有のコンパイラ フラグを設定する必要があります。そのようなフラグは、単一のプロセスにリンクするすべてのコードに一貫して設定しなければなりません。

マルチスレッド サーバを生成する場合、-t オプションを指定して buildserver(1) コマンドを実行する必要があります。これはマルチスレッド サーバの場合に必須のオプションです。ビルド時にこのオプションが指定されておらず、その後、MAXDISPATCHTHREADS の値が 1 を超えるコンフィグレーション ファイルを使用して新しいサーバを起動すると、警告メッセージがユーザ ログに記録され、サーバはシングルスレッドの動作に戻ります。

マルチスレッド環境で .c ファイルを .o ファイルにコンパイルする場合に必要なオペレーティング システム固有のコンパイラ パラメータを識別するには、-v オプションを指定して buildclient(1) または buildserver(1) をテスト ファイルで実行します。

関連項目

 


マルチスレッドおよびマルチコンテキスト アプリケーションのテスト

ここでは、以下の内容について説明します。

マルチスレッドおよびマルチコンテキスト アプリケーションのテスト時の推奨事項

マルチスレッドやマルチコンテキストのコードをテストする場合、以下を行うことをお勧めします。

マルチスレッドおよびマルチコンテキスト アプリケーションのトラブル シューティング

エラーの原因を調べる場合、まず TPMULTICONTEXTS フラグが設定されているかどうか、またその設定内容を確認します。このフラグが設定されていないこと、または正しく設定されていないことが原因でよくエラーが起こります。

tpinit( ) の TPMULTICONTEXTS フラグの間違った使用

TPMULTICONTEXTS フラグを使用できない場合にこのフラグがプロセスに設定されているとき、または TPMULTICONTEXTS を設定する必要がある場合に設定されていないとき、tpinit(3c)-1 を返し、tperrnoTPEPROTO を設定します。

TPMULTICONTEXTS が設定されていない場合の tpinit() の呼び出し

TPMULTICONTEXTS が設定されていない場合に tpinit(3c) が呼び出されると、この関数はシングルコンテキスト アプリケーションで呼び出されたときと同じように動作します。tpinit() が既に 1 回呼び出されている場合、それ以降の tpinit() 呼び出しで TPMULTICONTEXTS フラグが設定されていなくても、この関数は正常に終了します。これは、アプリケーション内の TUXCONFIG または WSNADDR 環境変数の値が変更されている場合にも当てはまります。TPMULTICONTEXTS フラグを設定せずに tpinit() を呼び出すことは、マルチコンテキスト モードではできません。

クライアントがアプリケーションに参加していない場合に、tpinit(3c) を呼び出す別の関数の呼び出しの結果として、暗黙的に tpinit() が呼び出されると、Oracle Tuxedo システムでは TPMULTICONTEXTS フラグが設定されずに tpinit() が呼び出されたと解釈されます。これは、以降の tpinit() 呼び出しでどのフラグが使用されるかを判断するためです。

ほとんどの ATMI 関数は、既にマルチコンテキスト モードで動作しているプロセスのコンテキストに対応付けされていないスレッドに呼び出された場合、tperrno(5)=TPEPROTO が設定されて失敗します。

スレッドのスタック サイズの不足

一部のオペレーティング システムでは、オペレーティング システムのデフォルトのスレッド スタック サイズが Oracle Tuxedo システムで使用するには十分ではありません。Compaq Tru64 UNIX と UnixWare の 2 つのオペレーティング システムは、サイズが小さいことが認識されています。デフォルトのスレッド スタック サイズのパラメータが使用されている場合に、スタックを多用する関数がメイン スレッド以外のスレッドで呼び出されると、これらのプラットフォーム上のアプリケーションはコア ダンプします。通常、生成されるコア ファイルから、スタック サイズの不足が問題の原因であることはわかりません。

サーバ ディスパッチ スレッドやクライアントの非請求メッセージ スレッドなど、Oracle Tuxedo システムで独自のスレッドが生成される場合、これらのプラットフォームのデフォルトのスタック サイズのパラメータを適切な値に調整できます。ただし、アプリケーションで独自のスレッドが生成される場合、アプリケーションで十分なスタック サイズを指定する必要があります。Oracle Tuxedo システムにアクセスするスレッドには、最低 128 K を指定してください。

Compaq Tru64 UNIX および POSIX スレッドが使用されるそのほかのシステムでは、スレッドのスタック サイズは、pthread_create() を呼び出す前に pthread_attr_setstacksize() を呼び出して指定します。UnixWare では、スレッドのスタック サイズは thr_create() の引数として指定されます。この問題の詳細については、お使いのオペレーティング システムのマニュアルを参照してください。

マルチスレッドおよびマルチコンテキスト アプリケーションのエラー処理

エラーはユーザ ログに記録されます。シングルコンテキスト モードでもマルチコンテキスト モードでも、各エラーに対して次の情報が記録されます。

process_ID.thread_ID.context_ID

関連項目


  ページの先頭       前  次