システムインタフェース

プロセス間通信

この節では、Solaris 2.x のプロセス間通信 (IPC) 機能を、実時間処理との関連で説明します。シグナル、パイプ、FIFO (名前付きパイプ)、メッセージ待ち行列、共用メモリ、ファイルマッピング、およびセマフォについて説明します。プロセス間通信に役立つライブラリ、関数、およびルーチンについては、第 7 章「プロセス間通信」と『SunOS Reference Manual』の Section 3「Library Routines」を参照してください。

概要

実時間処理は、しばしば高速な高いバンド幅のプロセス間通信を必要とします。どの機構を使用すればよいかは機能的な要求によって決まり、相対的な性能はアプリケーションの特性に依存します。

UNIX での従来のプロセス間通信の方法はパイプですが、パイプはフレーム上の問題を生じます。複数の人がメッセージを書いた結果が混合したり、あるメッセージを複数の人が読むと分断されてしまったりすることがあります。

IPC のメッセージは、ファイルの読み取りや書き込みと似たものです。これは 2 つ以上のプロセスが 1 つの媒体によって通信しなければならない場合、バイプより使いやすいです。

IPC の共用セマフォ機能では、プロセスの同期をとることができます。共用メモリは最も高速なプロセス間通信の形式です。共用メモリの主な長所は、メッセージデータのコピーが不要な点です。共用メモリアクセスの同期をとるには、通常はセマフォの機構を使用します。

シグナル

シグナルを使用してプロセス間で少量の情報を送信できます。次のように、送り側は sigqueue(3R) 関数を使用して、少量の情報とともにシグナルをターゲットプロセスに送信します。

ターゲットプロセスは、以降に発生した保留状態のシグナルも待ち行列に入れるため、指定されたシグナルの SA_SIGINFO ビットを設定していなければなりません (詳細は、sigaction(2) のマニュアルページを参照してください)。

ターゲットプロセスは、シグナルを同期または非同期に受信できます。シグナルをブロッキングしたまま (sigprocmask(2) のマニュアルページを参照)、sigwaitinfo(3R) または sigtimedwait(3R) を呼び出すと、シグナルは、siginfo_t 引数の si_value メンバーに格納されている、sigqueue(3R) の呼び出し側によって送信された値と同期をとって受信されます。シグナルのブロッキングを解除しておくと、シグナルは sigaction(2) によって指定されたシグナルハンドラに配信され、値はハンドラへの siginfo_t 引数の si_value に設定されます。

関連づけられた値を持つシグナルで、送信しても配信されないものの数は、1 プロセスあたり固定です。{SIGQUEUE_MAX}}個のシグナルの記憶領域は、sigqueue(3R) を最初に呼び出した時点で割り当てられます。その後 sigqueue() を呼び出すと、ターゲットプロセスの待ち行列にシグナルが正常に入るか、制限時間内で異常終了します。

パイプ

パイプは、プロセス間の一方方向の通信を提供します。プロセスがパイプで通信するには、共通の祖先を持っていなければなりません。パイプを通して渡されるデータは、通常の UNIX バイトストリームとして扱われます。パイプについては、「パイプ」を参照してください。

名前付きパイプ

Solaris 2.x では名前付きパイプ (FIFO) が用意されています。FIFO はディレクトリ内の名前付きエンティティなので、パイプより柔軟性があります。FIFO が作成されると、適切なアクセス権を持っていればどのプロセスでも FIFO を開くことができます。プロセスは親を共用している必要はなく、親がパイプを初期化して子孫に渡す必要もありません。詳細は、「名前付きパイプ」を参照してください。

メッセージ待ち行列

メッセージ待ち行列は、プロセス間で通信するもう 1 つの手段を提供します。任意の数のプロセスが 1 つのメッセージ待ち行列だけで送受信できます。メッセージは、バイトストリームとしてではなく、任意の大きさのブロッキングとして渡されます。メッセージ待ち行列は、System V 版と POSIX 版の両方で提供されています。詳細は、「System V メッセージ」「POSIX メッセージ」を参照してください。

セマフォ

セマフォは、共用資源へのアクセスの同期をとる機構です。セマフォも、System V と POSIX の両方で提供されています。System V セマフォは非常に柔軟性がありますが、非常に重量級です。POSIX セマフォは、極めて軽量です。詳細は、「System V セマフォ」「POSIX セマフォ」を参照してください。

セマフォを使用すると、この章で前述した技法によって明示的に回避しない限り、優先順位の反転が生じる場合があるので注意してください。

共用メモリ

プロセスが通信するための最も高速な方法は、直接メモリの共用セグメントを使用した場合です。共通メモリ領域が共用しているプロセスのアドレス空間に追加されます。アプリケーションは、データを格納を使用することでデータを送信し、データを取り出すことで通信データを受信します。Solaris 2.x では、共用メモリのための機構として、メモリにマッピングされたファイル、SVIPC 共用メモリ、POSIX 共用メモリの 3 つの方法を提供しています。

共用メモリを使用するときの最も大きな問題点は、3 つ以上のプロセスが同時に共用メモリに読み取りや書き込みを行おうとすると結果が正しくなくなる場合があることです。詳細は、「共用メモリの同期」を参照してください。

メモリにマッピングされたファイル

mmap(2) インタフェースは、共用メモリセグメントを呼び出し側のアドレス空間に接続します。呼び出し側は、アドレスと長さによって共用セグメントを指定します。呼び出し側は、アクセス保護フラグとマッピングされたページを管理する方法も指定しなければなりません。mmap(2) を使用して、ファイルまたはファイルのセグメントをプロセスのメモリにマッピングすることもできます。この技法は、あるアプリケーションでは非常に便利ですが、マッピングされたファイルセグメントへの格納が暗黙の入出力になる場合があるということを忘れがちです。それ以外の場合では、結合されているプロセスの応答時間が予測できないものになることもあります。msync(3C) は、指定したメモリセグメントのその時のまたは最終的なコピーをパーマネント記憶領域に作成します。詳細は、「メモリ管理インタフェース」を参照してください。

ファイルなしメモリマッピング

0 の特別ファイルである /dev/zero(4S) は、名前がなく 0 で初期化されたメモリオブジェクトを作成するのに使用できます。メモリオブジェクトの長さはマッピングを含むページの最小の番号になります。オブジェクトは、共通の先祖プロセスをもつ子孫だけが共用できます。

SVIPC 共用メモリ

shmget(2) 呼び出しを使用して、共用メモリセグメントの作成と既存の共用メモリセグメントを取得できます。shmget 関数は、ファイル識別子に似た識別子を戻します。shmat(2) を呼び出すと、mmap(2) とほとんど同じように共用メモリセグメントがプロセスメモリの仮想セグメントになります。詳細は、「System V 共用メモリ」を参照してください。

POSIX 共用メモリ

POSIX 共用メモリは System V 共用メモリの変形で、若干の違いはありますが同様の機能を提供します。詳細は、「POSIX 共用メモリ」を参照してください。

共用メモリの同期

共用メモリでは、メモリの一部が 1 つ以上のプロセスのアドレス空間にマッピングされます。アクセスを協調させる方法は自動的には提供されないため、2 つのプロセスが同時に同じ場所の共用メモリに書き込もうとすることがあります。このため共用メモリは、通常はプロセスの同期をとるセマフォやその他の機構と一緒に使用します。System V セマフォと POSIX セマフォは、両方ともこの目的のために使用できます。マルチスレッドライブラリに提供されている相互排他ロッキング、リーダロッキングとライタロッキング、セマフォ、および条件変数もこの目的のために使用できます。

IPC および同期の機構の選択

アプリケーションには特定の機能上の要求があって、それによってどの IPC 機構を使用するかが決まります。いくつかの機構が使用できる場合は、アプリケーションの作成者が、そのうちどれが最もアプリケーションに適しているかを決定します。アプリケーションの特性によって、IPC および同期の機構を選択してください。アプリケーションで使用される様々な長さのメッセージの組み合わせについて各機構のスループットを測定し、どの機構の応答が最も良いかを調べてください。