II-8-7. パイプによるプロセス間通信

プロセス間通信を実現する手法のひとつとして、パイプを利用した通信手順を紹介する。パイプの作成と入出力制御、名前付きパイプの利用方法などについて、関連する関数を利用してプロセス間通信を実現するための具体的な手順を説明する。

【学習の要点】

* パイプは、一次元バイト列であり、プロセス間でプロセス間通信を行うひとつの方法である。

* パイプはpipeシステムコールを用いて生成する。

* パイプで通信できるプロセス同士は、互いに記述子を共有できる間柄(多くの場合、親子関係)になければならない。

* 親子関係にないプロセス同士がパイプを用いて通信を行うには、FIFO(名前付きパイプとも呼ばれる)を使用できる。この場合は、ファイルシステム上のスペシャルファイルを共有することによって同期が取られる。

図II-8-7. 親子プロセス間でパイプを作成

【解説】

1) パイプ

* パイプは、名前を持たないカーネル内のバッファであり、pipeシステムコールを用いて作成する。pipeは、2つのファイル記述子を作成する。それぞれ、読み込み用と書き出し用で、プロセスはこれらの記述子に対するreadやwriteシステムコールを通してパイプにアクセスする。作成例を以下に示す。

int p[2];

pipe(p);

* pipeによって作成されたファイル記述子を、プロセス間で共有することで、2つのプロセスはカーネル内の同じバッファ領域にアクセスすることが可能である。これは、これら2つのプロセスが互いに任意のデータをやり取りできることを意味する。

* forkによって親子関係を持つプロセス同士では記述子の共有が容易であるため、ほとんどの場合パイプはこの状況下で使用される。

* ひとつのパイプは単方向のデータの流れを提供する。これに従って、forkによって記述子を共有するプロセスは、それぞれ一方は呼び込み用記述子をクローズ、他方は書き出し用記述子をクローズする。

* 双方向のデータの流れが必要な場合は、パイプを二つ用意する。

* パイプはシェルで最もよく利用される。これは、読み込み用の記述子を標準入力、書き込み用の記述子を標準出力にそれぞれマップすることで行なう。

2) FIFO

* FIFO (First In, First Out) は、パイプに似た機能を提供する特殊ファイルである。スペシャルファイルであることから、これはファイルシステムの名前空間上にマップされる。このため、これを名前付きパイプと呼ぶことがある。

* FIFOは、mkfifoシステムコールを用いて作成する。

mkfifo(“/tmp/myfifo”, mode);

* パイプと違い、ファイルシステムのパスと関連付けられる(名前を持つ)ため、関係のないプロセス同士が名前で同一FIFOにアクセスすることができる。

3) パイプ、FIFOに共通の性質

* パイプもFIFOもカーネル内に置かれるバッファである。バッファの長さはシステムに依存し、POSIX.1では最低512バイトを要求する。

* パイプやFIFOのサイズに収まるデータをwriteによって書き込んだ場合、writeは不可分性を保証する。もし、パイプやFIFOのサイズ以上のデータを書き込んだ場合にはこれは保証されない。

* パイプやFIFOは、何もしなければブロッキングモードのファイル記述子を使用することになる。fcntlを使用して記述子を非ブロッキングモードに設定することで、パイプまたはFIFOの処理を非ブロッキングモードで実行できる。

OSS Course Naviのコンテンツは IPA OSS モデルカリキュラムを基としています。

フォーラム会員企業専用

記事配信

コンテンツ配信

ユーザログイン