ONC+ 開発ガイド

マルチスレッドサーバの概要

Solaris 2.4 より前のバージョンでは、RPC サーバはシングルスレッドでした。つまり、クライアント側から要求が来るごとに処理していました。たとえば、2 つの要求を同時に受け取り、最初の処理に 30 秒、次の処理に 1 秒かかるとすると、2 つめの要求を出したクライアントは最初の処理が完了するまで待たなければなりません。これは、各 CPU が異なる要求を同時に処理するマルチプロセッササーバ環境を利用できず、他の要求がサーバによって処理することができるのに 1 つの要求の I/O の完了を待っている状態が生じ、望ましいものではありません。

Solaris 2.4 以降 の RPC ライブラリでは、サービス開発者がエンドユーザにより良いパフォーマンスを提供するマルチスレッドサーバを作成できる機能を追加しました。サーバのマルチスレッドの 2 つのモード、自動マルチスレッドモードとユーザ・マルチスレッド・モードは、TI-RPC でサポートされます。

自動モードでは、サーバは、クライアント要求を受信するごとに新規スレッドを自動的に作成します。このスレッドは要求を処理し、応答してから終了します。ユーザモードでは、サービス開発者が、入って来るクライアント要求を同時に処理するスレッドを作成、管理します。自動モードはユーザモードより使用はしやすいのですが、ユーザモードの方が特別な要件を必要とするサービス開発者に対して柔軟性があります。


注 -

RPC マルチスレッド対応アプリケーションを作成する場合は常に、スレッドライブラリをリンクしなければなりません。コンパイルコマンドで -lthread を指定して、スレッドライブラリを最後にリンクするようにしなければなりません。


サーバ側のマルチスレッドをサポートする呼び出しでは、rpc_control()svc_done() がサポートされています。これらの呼び出しによってサーバ側でマルチスレッド処理が行なえるようになりました。rpc_control() 呼び出しがマルチスレッドモードを設定するために、自動モードとユーザモードの両方で使用されます。サーバが自動モードを使用する場合には、svc_done() を呼び出す必要はありません。ユーザモードの場合には、サーバが要求処理からのリソースを再要求できるようにするため、svc_done() は各クライアント要求が処理されてから呼び出されなければなりません。さらにマルチスレッド RPC サーバは、svc_run() をマルチスレッド対応で呼び出さなければなりません。svc_getreqpoll()svc_getreqset() は、MT アプリケーションでは安全ではありません。


注 -

サーバプログラムが新規インタフェース呼び出しを行わない場合には、デフォルトのモードのシングルスレッドモードのままです。


サーバが使用しているモードに関係なく、RPC サーバ手続きはマルチスレッド対応にしなければなりません。通常これは、すべての静的変数とグロール変数が mutex ロックで保護される必要がある、ということです。相互排他と他の同期 API は、synch.h で定義されます。さまざまな同期インタフェースのリストは、condition(3T)rwlock(3T)mutex(3T) を参照してください。

図 4-2 は、マルチスレッドモードのどちらかで実行されるサーバの実行タイミングを示します。

図 4-2 マルチスレッド RPC サーバのタイミング図

Graphic

サービス・トランスポート・ハンドルの共有

サービス・トランスポート・ハンドル、SVCXPRT には、引き数を復号化するための領域と結果をコード化するための領域である 1 つのデータ領域があります。したがって、デフォルトでは、シングルスレッドモードであり、この構造は、これらの操作を行う関数を呼び出すスレッド間では自由に共有することはできません。ただし、サーバが、マルチスレッド自動モードまたはユーザモードにある場合には、この構造のコピーは、同時要求処理を可能にするために、サービスディスパッチ用のプログラムに引き渡されます。これらの状況では、ルーチンのマルチスレッド対応ではない一部のルーチンがマルチスレッド対応となります。特別に注意書きがない場合には、サーバインタフェースは通常、マルチスレッド対応です。サーバ側のインタフェースについての詳細は、rpc_svc_calls(3N) マニュアルページを参照してください。