日本-日本語
日本HPホーム 製品 & サービス OpenVMS製品情報
≫  お問い合わせ


OpenVMS マニュアル


 

OpenVMS ドキュメント
ライブラリ

タイトルページ
目次
まえがき
第 1 章:はじめに
第 2 章:入出力について
第 3 章:文字/文字列/引数リスト関数
第 4 章:エラー処理とシグナル処理
第 5 章:サブプロセス関数
第 6 章:Curses画面管理関数とマクロ
第 7 章:算術関数
第 8 章:メモリ割り当て関数
第 9 章:システム関数
第 10 章:国際化ソフトウェアの開発
第 11 章:日付/時刻関数
第 12 章:シンボリックリンクとPOSIXパス名
付録 A:各OSバージョンでサポートする関数一覧
付録 B:非標準ヘッダに複製されているプロトタイプ
索引
PDF
OpenVMS ホーム

HP OpenVMS
HP C ランタイム・ライブラリ・リファレンス・マニュアル (上巻)


目次 索引



HP C RTL では,リエントラントのサポートが向上し,強化されました。次の種類のリエントラントがサポートされます。

  • AST リエントラントでは,_BBSSI 組み込み関数を使用して, RTL コードのクリティカル・セクションの周囲で単純なロックを実行しますが,ロックされたコード領域で非同期システム・トラップ (AST) も必要になることがあります。この種のロックは,AST コードに HP C RTL I/O ルーチンへの呼び出しが含まれているときに使用しなければなりません。
    AST リエントラントを指定しないと,I/O ルーチンが異常終了することがあり, errnoが EALREADY に設定されます。

  • MULTITHREAD リエントラントは,DECthreads ライブラリを使用するプログラムなど,スレッド・プログラムで使用するように設計されています。このリエントラントは DECthreads ロックを使用し,AST を無効にしません。この形式のリエントラントを使用するには,システムで DECthreads が使用可能でなければなりません。

  • TOLERANT リエントラントでは,_BBSSI 組み込み関数を使用して, RTL コードのクリティカル・セクションの周囲で単純なロックを実行しますが, AST は禁止されません。この種のロックは,AST が使用され,ただちに配布しなければならないときに使用する必要があります。

  • NONE は HP C RTL で最適な性能を提供しますが, RTL コードのクリティカル・セクションの周囲で絶対にロックを行いません。実行スレッドが HP C RTL を呼び出す AST によって割り込まれる可能性がない場合は,シングル・スレッド環境でのみ使用するようにしなければなりません。

デフォルトのリエントラント・タイプは TOLERANT です。

リエントラント・タイプを設定するには, /REENTRANCY コマンド・ライン修飾子を指定してコンパイルするか, decc$set_reentrancy関数を呼び出します。 この関数は非 AST レベルから排他的に呼び出さなければなりません。

複数のスレッドまたは AST を使用するアプリケーションをプログラミングする場合は,次の 3 つのクラスの関数について考慮してください。

  • 内部データのない関数

  • スレッドだけで有効な内部データのある関数

  • プロセス単位の内部データがある関数

ほとんどの関数は,まったく内部データのない関数です。このような関数の場合,同期化が必要になるのは,パラメータがマルチスレッドのアプリケーションで使用されるか,または AST コンテキストと非 AST コンテキストの両方でパラメータが使用される場合だけです。たとえば, strcat関数は一般にはスレッド・セーフですが,次の例は安全でない使い方を示しています。

extern char buffer[100]; 
void routine1(char *data) { 
    strcat( buffer, data ); 
} 

routine1が複数のスレッドで並列に実行されるか,または routine1がそのルーチンを呼び出す AST ルーチンによって割り込まれると, strcat呼び出しの結果は予測不能になります。

2 番目のクラスの関数は,スレッドだけで有効な静的データを含む関数です。通常,これらの関数は,アプリケーションが文字列の格納領域を解放することを許可されていない状況で,文字列を返すライブラリ内のルーチンです。これらのルーチンはスレッド・セーフですが,AST リエントラントではありません。つまり,並列に呼び出しても安全ですが,各スレッドはそれぞれ独自のデータのコピーを保有します。同じルーチンが非 AST コンテキストで実行される可能性がある場合は,これらのルーチンを AST ルーチンから呼び出すことはできません。このクラスのルーチンは次のとおりです。

asctime        stat 
ctermid        strerror  
ctime          strtok 
cuserid        VAXC$ESTABLISH 
gmtime         the errno variable 
localtime      wcstok 
perror                

使用している TCP/IP 製品がスレッド・セーフの場合,すべてのソケット関数もこのリストに含まれます。

3 番目のクラスの関数は,プロセス単位のデータに影響する関数です。これらの関数はスレッド・セーフではなく,AST リエントラントでもありません。たとえば, sigsetmaskはプロセス単位のシグナル・マスクを確立します。次のようなルーチンについて考えてみましょう。

void update_data 
base() 
{ 
    int old_mask; 
 
    old_mask = sigsetmask( 1 << (SIGINT - 1)); 
        /* Do work here that should not be aborted. */ 
    sigsetmask( old_mask ); 
} 

update_databaseが複数のスレッドで並列して呼び出された場合,スレッド 2 が強制終了されない作業をまだ実行している間に,スレッド 1 は SIGINT のブロックを解除する可能性があります。

このクラスのルーチンは次のとおりです。

  • すべての signalルーチン

  • すべての execルーチン

  • exit_exitnicesystemwaitgetitimersetitimersetlocaleルーチン

  注意
一般に, UTC ベースの時刻関数はメモリ内のタイム・ゾーン情報に影響を与える可能性があり,これはプロセス単位のデータです。しかし,アプリケーションが実行されている間,システム・タイム・ゾーンが変化せず ( これは一般的な場合です ),タイム・ゾーン・ファイルのキャッシュが許可されている場合 ( これはデフォルトです ),時刻関数 asctime_rctime_rgmtime_rlocaltime_r_rバリアントはスレッド・セーフであり,かつ AST リエントラントです。

しかし,アプリケーションの実行中にシステム・タイム・ゾーンが変化する可能性がある場合や,タイム・ゾーン・ファイルのキャッシュが許可されていない場合は, UTC ベースの時刻関数のバリアントはどちらも 3 番目のクラスの関数に属し,スレッド・セーフでも AST リエントラントでもありません。

次に示す一部の関数は,リエントラントであるかどうかに関係なく,本質的にスレッド・セーフではありません。

execl      exit 
execle     _exit 
execlp     nice 
execv      system 
execve     vfork 
execvp 



1.8.2 マルチスレッドの制限事項

同じアプリケーション内でマルチスレッド・プログラミング・モデルと OpenVMS AST プログラミング・モデルを混在させることは推奨できません。アプリケーションで,どのスレッドが AST によって割り込まれるかを制御することはできません。この結果,AST ルーチンからも必要とされるリソースをスレッドが保有している場合,リソースのデッドロックが発生します。次の関数はミューテクスを使用します。リソース・デッドロックの発生を回避するには,マルチスレッド・アプリケーションで AST 関数からこれらを呼び出さないようにしなければなりません。

  • すべての I/O 関数

  • すべてのソケット関数

  • すべてのシグナル関数

  • vforkexecwaitsystem

  • catgets

  • set_new_handler(C++ のみ)

  • getenv

  • randsrand

  • exit_exit

  • clock

  • nice

  • times

  • ctimelocaltimeasctimemktime



1.9 64 ビット・ポインタのサポート (Integrity,Alpha)

このセクションの説明は, OpenVMS Alpha Version 7.0 以降で 64 ビット仮想メモリ・アドレッシングを使用する必要のあるアプリケーション開発者を対象にしています。

OpenVMS Alpha の 64 ビット仮想アドレッシングのサポートでは, Alpha アーキテクチャで定義されている 64 ビット仮想アドレス空間が OpenVMS オペレーティング・システムとそのユーザの両方から使用できるようになっています。また,従来の 32 ビットの制限を超えて動的にマッピングされたデータにアクセスするために,プロセス単位の仮想アドレッシングも可能です。

OpenVMS Alpha Version 7.0 以降のシステムの HP C ランタイム・ライブラリでは, 64 ビット・ポインタをサポートするために次の機能が提供されます。

  • 既存のプログラムとの間で,バイナリ・レベルおよびソース・レベルの互換性が保証されます。

  • 64 ビットのサポート機能を活用するように変更されていないアプリケーションには影響を与えません。

  • 64 ビット・メモリを割り振るメモリ割り当てルーチンの機能が拡張されています。

  • 64 ビット・ポインタに対応するために,関数パラメータのサイズが拡大されました。

  • 呼び出し元が使用するポインタ・サイズに関する情報が必要な関数は,二重に実装されています。

  • 適切な実装を呼び出すことができるように, DEC C Version 5.2 以降のコンパイラで新しい情報が提供されるようになりました。

  • ポインタ・サイズが混在するアプリケーションで,32 ビット形式と 64 ビット形式の関数を明示的に呼び出すことができる機能が提供されます。

  • 32 ビット・アプリケーションと 64 ビット・アプリケーションで使用するために, 1 つの共用可能イメージが提供されます。



1.9.1 HP C ランタイム・ライブラリの使用

OpenVMS Alpha Version 7.0 以降のシステムでは, HP C ランタイム・ライブラリは 64 ビット・ポインタを生成したり,受け付けることができます。 64 ビット・ポインタで使用される第 2 のインタフェースを必要とする関数は,対応する 32 ビットの関数と同じオブジェクト・ライブラリおよび共用可能イメージに存在します。新しいオブジェクト・ライブラリや共用可能イメージが提供されるわけではありません。 64 ビット・ポインタを使用する場合,リンク・コマンドやリンク・オプション・ファイルを変更する必要はありません。

HP C の 64 ビット環境では,アプリケーションは 32 ビット・アドレスと 64 ビット・アドレスの両方を使用できます。ポインタ・サイズの操作方法の詳細については,『HP C User's Guide for OpenVMS Systems』の /POINTER_SIZE 修飾子と, #pragma pointer_sizeおよび #pragma required_pointer_sizeプリプロセッサ・ディレクティブを参照してください。

/POINTER_SIZE 修飾子には,32 または 64 の値を指定する必要があります。この値は,コンパイル・ユニットの内部でデフォルト・ポインタ・サイズとして使用されます。32 ビット・ポインタを使用して 1 組のモジュールをコンパイルし,64 ビット・ポインタを使用して別の 1 組のモジュールをコンパイルすることができます。これらの 2 組のモジュールを相互に呼び出す場合は,注意を払う必要があります。

/POINTER_SIZE 修飾子の使用は, HP C RTL ヘッダ・ファイルの処理にも影響を与えます。 32 ビット版と 64 ビット版の両方がある関数の場合, /POINTER_SIZE を指定すると,修飾子に指定された実際の値とは無関係に,関数プロトタイプは両方の関数にアクセスできます。さらに,修飾子に指定された値によって,そのコンパイル・ユニットで呼び出すデフォルトの実装が決定されます。

#pragma pointer_sizeおよび #pragma required_pointer_sizeプリプロセッサ・ディレクティブを使用すると,コンパイル・ユニットの内部で有効なポインタ・サイズを変更することができます。デフォルトのポインタ・サイズを 32 ビット・ポインタに設定した後,モジュール内で特定のポインタを 64 ビット・ポインタとして宣言することができます。また,64 ビット・メモリ領域からメモリを取得するには, malloc_malloc64という形式を特別に呼び出す必要もあります。

1.9.2 メモリへの 64 ビット・ポインタの取得

HP C RTL には,新たに割り当てられたメモリへのポインタを返す関数が数多くあります。これらの各関数では,アプリケーションはポインタによって示されるメモリを所有し,そのメモリを解放する責任があります。

メモリを割り当てる関数は次のとおりです。

malloc
calloc
realloc
strdup

これらの各関数には,32 ビット版と 64 ビット版があります。 /POINTER_SIZE 修飾子を使用すると,次の関数も呼び出すことができます。

_malloc32_malloc64
_calloc32_calloc64
_realloc32_realloc64
_strdup32_strdup64

/POINTER_SIZE=32 を指定した場合,すべての mallocの呼び出しはデフォルトで _malloc32に設定されます。

/POINTER_SIZE=64 を指定した場合,すべての mallocの呼び出しはデフォルトで _malloc64に設定されます。

アプリケーションで 32 ビットのメモリ割り当てルーチンを呼び出す場合も, 64 ビットのメモリ割り当てルーチンを呼び出す場合も, free関数は 1 つしかありません。この関数はどちらのポインタ・サイズも受け付けます。

64 ビット・メモリを指すポインタを返すのは,メモリ割り当て関数だけであるということに注意しなければなりません。呼び出し元のアプリケーションに返されるすべての HP C RTL 構造体ポインタ (FILE,WINDOW,DIR など ) は常に 32 ビット・ポインタです。このため,32 ビットと 64 ビットの両方の呼び出し元アプリケーションがこれらの構造体ポインタをアプリケーションの内部で渡すことができます。

1.9.3 HP C ヘッダ・ファイル

OpenVMS に付属のヘッダ・ファイルでは, 64 ビット・ポインタがサポートされます。シグネチャにポインタが含まれる各関数プロトタイプは,受け付けるポインタのサイズを示すように作成されています。

32 ビット・ポインタは,引数として 32 ビットまたは 64 ビットのポインタを受け付ける関数に対して,引数として渡すことができます。

しかし,32 ビット・ポインタを受け付ける関数に対する引数として, 64 ビット・ポインタを渡すことはできません。このような処理はコンパイラで診断され,MAYLOSEDATA メッセージが出力されます。診断メッセージ IMPLICITFUNC は,コンパイラがその関数の呼び出しでポインタ・サイズの追加確認を実行できないことを示します。この関数が HP C RTL 関数の場合は,その関数を定義しているヘッダ・ファイルの名前については,『HP C ランタイム・ライブラリ・リファレンス・マニュアル (下巻)』「リファンレンス・セクション」を参照してください。

ポインタ・サイズに関する次のコンパイラ診断情報は役立ちます。

  • %CC-IMPLICITFUNC
    指定された関数を使用する前に,関数プロトタイプを見つけることができませんでした。コンパイラおよび実行時システムは,プロトタイプの定義をもとに,不正なポインタ・サイズの使用を検出します。適切なヘッダ・ファイルを取り込むことができないと,不正な結果が発生したり,ポインタが切り捨てられる可能性があります。

  • %CC-MAYLOSEDATA
    この操作を実行するには,切り捨てが必要です。この操作では,指定されたコンテキストで 64 ビット・ポインタをサポートしていない関数に 64 ビット・ポインタを渡す可能性があります。また,32 ビット・ポインタに戻り値を格納しようとする呼び出し元アプリケーションに,関数が 64 ビット・ポインタを返している可能性もあります。

  • %CC-MAYHIDELOSS
    このメッセージ ( 有効に設定されている場合 ) は,キャスト操作のために出力されていない実際の MAYLOSEDATA メッセージを確認するのに役立ちます。この警告を有効にするには,修飾子 /WARNINGS=ENABLE=MAYHIDELOSS を指定してコンパイルします。



1.9.4 影響を受ける関数

HP C RTL は,32 ビット・ポインタのみ, 64 ビット・ポインタのみ,またはその両方の組み合わせを使用するアプリケーションに対応します。 64 ビット・メモリを使用するには,少なくともアプリケーションの再コンパイルと再リンクが必要です。必要なソース・コードの変更の量は,アプリケーション自体,他のランタイム・ライブラリの呼び出し,使用するポインタ・サイズの組み合わせに応じて異なります。

64 ビット・ポインタのサポートに関して, HP C RTL 関数は次の 4 種類に分類できます。

  • ポインタ・サイズの選択の影響を受けない関数

  • どちらのポインタ・サイズも受け付けるように拡張された関数

  • 32 ビット版と 64 ビット版がある関数

  • 32 ビット・ポインタだけを受け付ける関数

アプリケーション開発者の立場から考えると,最初の 2 種類の関数は単一ポインタ・モードまたは複合ポインタ・モードで最も簡単に使用できます。

3 番目の関数は, 1 種類のポインタだけを使用してコンパイルする場合は変更が不要ですが,複合ポインタ・モードで使用する場合はソース・コードの変更が必要です。

4 番目の関数は, 64 ビット・ポインタを使用しなければならないときに注意する必要があります。


目次 索引

© 2012 Hewlett-Packard Development Company, L.P.