BEA Logo BEA Tuxedo Release 8.0

  BEA ホーム  |  イベント  |  ソリューション  |  パートナ  |  製品  |  サービス  |  ダウンロード  |  ディベロッパ・センタ  |  WebSUPPORT

 

   Tuxedo ホーム   |   C 言語を使用した BEA Tuxedo アプリケーションのプログラミング   |   先頭へ   |   前へ   |   次へ   |   目次

 


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

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

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

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

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

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

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

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

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

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

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

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

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

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


 

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


 

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

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

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

実行する関数

実行後のスレッドのコンテキスト状態

NULL コンテキスト

シングルコンテキスト

マルチコンテキスト

無効コンテキスト

TPMULTICONTEXTS が設定されていない tpinit()

シングルコンテキスト

シングルコンテキスト

エラー

エラー

TPMULTICONTEXTS が設定された tpinit()

マルチコンテキスト

エラー

マルチコンテキスト

エラー

TPNULLCONTEXT への tpsetctxt(3c)

NULL

エラー

NULL

NULL

コンテキスト 0 への tpsetctxt(3c)

エラー

シングルコンテキスト

エラー

エラー

コンテキスト > 0 への tpsetctxt(3c)

マルチコンテキスト

エラー

マルチコンテキスト

マルチコンテキスト

暗黙的な tpinit()

シングルコンテキスト

該当せず

該当せず

エラー

このスレッドでの tpterm()

NULL

NULL

NULL

NULL

このコンテキストの異なるスレッドでの tpterm()

該当せず

NULL

無効

該当せず


 

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

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

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

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

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

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

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

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

注記 tpbroadcast() の場合、ブロードキャスト・メッセージは特定のアプリケーションとの対応付けから送られたものとして識別されます。tpnotify(3c) の場合、通知は特定のアプリケーションとの対応付けから送られたものとして識別されます。tpinit() の注記については、「マルチスレッド・クライアントでのプロセス単位の関数とデータ構造体」を参照してください。

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

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

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

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

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

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

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

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

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

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

注記 コードを簡単にするために、エラー・チェックは省略してあります。

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

#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);
}

関連項目

 

先頭へ戻る 前のトピックへ 次のトピックへ