「プロセス間通信」の版間の差分

提供: UnixClassWiki
移動先: 案内検索
(System V IPC)
(System V IPC)
(同じ利用者による、間の11版が非表示)
1行目: 1行目:
 
== IPCとは ==
 
== IPCとは ==
  
プロセス実行中に他のプロセスと通信を行うための機構を考えます。通信とい
+
プロセス実行中に他のプロセスと通信を行うための機構を考えます。通信ということでは2つの方法を挙げることができます。
うことでは2つの方法を挙げることができます。
+
 
  
 
*  ローカルマシン内(もちろん動いているカーネルは1つという前提)で動作しているプロセス間での通信。
 
*  ローカルマシン内(もちろん動いているカーネルは1つという前提)で動作しているプロセス間での通信。
9行目: 9行目:
  
  
本章では前者のローカルマシン内での通信を取り上げます。もちろんローカル
+
本章では前者のローカルマシン内での通信を取り上げます。もちろんローカルマシン内で動作するプロセス同士でもネットワーク経由と同じようにTCP/IPを使って通信できますが、本章のプロセス間通信の説明からはTCP/IPは除いておきます。
マシン内で動作するプロセス同士でもネットワーク経由と同じようにTCP/IPを
+
使って通信できますが、本章のプロセス間通信の説明からはTCP/IPは除いてお
+
きます。
+
  
  
ここでのプロセス通信(InterProcess Communication / IPC )とは、名前つき
+
ここでのプロセス通信(InterProcess Communication / IPC )<ref> LinuxのIPCについては次の発表スライドが参考になります。 Michael Kerrisk, "An introduction to
パイプ(named pipe)、pipe、UNIXドメインソケット(ローカルIPC)、セマフォー
+
Linux IPC",  linux.conf.au 2013 http://man7.org/conf/lca2013/IPC_Overview-LCA-2013-printable.pdf </ref>とは、名前つきパイプ(named pipe)、pipe、UNIXドメインソケット(ローカルIPC)
やあるいはシェアードメモリなどを指しています。これらにより高速にプロセ
+
セマフォー<ref>Linuxのセマフォーに関しては次のWebサイトが詳しい。 http://www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html</ref>やあるいはシェアードメモリなどを指しています。これらにより高速にプロセス間でデータをやりとりするためのメカニズムと捉えます。Linuxでは、
ス間でデータをやりとりするためのメカニズムと捉えます。Linuxでは、
+
System Vで使われていたプロセス間通信の機能、4.2BSDで採り入れられたソケット、名前つきパイプが使えます。
System Vで使われていたプロセス間通信の機能、4.2BSDで採り入れられたソケッ
+
ト、名前つきパイプが使えます。
+
  
  
28行目: 23行目:
  
  
プロセス間通信の機能というと、System Vで使われていたプロセス間通信の機
+
プロセス間通信の機能というと、System Vで使われていたプロセス間通信の機能(System V IPC)のセマフォー<ref>セマフォーとは、元々は列車運行で列車が単線の区間に入ることを許されているか、あるいは待つのかを示す信号機なのだそうです。</ref>(semaphore)、メッセージキュー(message
(System V IPC)のセマフォー
+
<ref>セマフォーとは、元々は列車運行で列車が単線の区間に入ることを許されてい
+
るか、あるいは待つのかを示す信号機なのだそうです。</ref>
+
(semaphore)、メッセージキュー(message
+
 
queues)、シェアードメモリ(shared memory)が有名です。
 
queues)、シェアードメモリ(shared memory)が有名です。
  
  
ソフトウェアの世界では、複数のプロセスが同じ資源の競合を避けるために、
+
ソフトウェアの世界では、複数のプロセスが同じ資源の競合を避けるために、使われる機能で、たとえば複数のプロセスが同時にファイルを書き込みするタイミングが同じになってしまわないように、セマフォを使って待ちます。
使われる機能で、たとえば複数のプロセスが同時にファイルを書き込みするタ
+
セマフォは(ファイルのロックなどを使うよりも)高速に処理できるので、たとえばデータベースのようなアプリケーションでの処理のロックなどに使われています。
イミングが同じになってしまわないように、セマフォを使って待ちます。セマ
+
しかし、同様な処理はmmapを使っても可能ですので、今日ではセマフォがなくては実装ができない、というわけではありません。むしろ、互換性のために残していると考えた方が良いでしょう。また今日ではSystem V IPCは、相対的に「重い」処理と考えられています。
フォは高速に処理できるので、たとえばデータベースのようなアプリケーショ
+
一方、POSIX IPC はマルチスレッドで安全であり、かつ、System V IPCより軽量なのでPOSIX IPCの利用が推奨されています。<ref>IBMのdeveloper worksのサイトの中にある "[https://www.ibm.com/developerworks/jp/linux/library/l-semaphore/index.html System V のセマフォー API を使用して POSIX のセマフォー API を実装する]"  の本文中に「POSIX のセマフォーは System V のセマフォーよりもはるかに軽量」という記述も存在する。</ref>
ンでの処理のロックなどに使われています。しかし、同様な処理はmmapを使っ
+
ても可能ですので、今日ではありまり価値があるとはいえません。むしろ、互
+
換性のために残していると考えた方が良いでしょう。
+
  
  
50行目: 38行目:
  
  
メッセージキューは古いアプリケーションを動かすための互換性のために残さ
+
System V IPCを使ってのメッセージキューは古いアプリケーションを動かすための互換性のために残されているようなもと考えても良いレベルになって来ています。今日では新規のプログラムに使うような場面を見かけたことがありません。最近ではメッセージキューを使う所を名前つきパイプで済ますことができます。シェアードメモリもmmapが使えます。
れているようなもと考えても良いレベルになって来ています。今日では新規の
+
 
プログラムに使うような場面を見かけたことがありません。最近ではメッセー
+
 
ジキューを使う所を名前つきパイプで済ますことができます。シェアードメモ
+
Linuxのカーネルが2.6以降ではPOSIX IPCが使えるようになりました。新しくプログラムを作る場合で、メッセージキューなどを使いたい時はSystem V IPCではなくPOSIX IPCを使うべきでしょう。
リもmmapが使える今日ではあまり特別な価値はありません。現在もあるのは、
+
 
互換性のためにあると考えてかまわないでしょう。
+
== POSIX IPC ==
 +
 
 +
TBD
  
 
== 名前つきパイプ ==
 
== 名前つきパイプ ==
127行目: 117行目:
  
  
これはTCP/IPネットワーク接続の機能のインタフェースと同じものを用意して、
+
これはTCP/IPネットワーク接続の機能のインタフェースと同じものを用意して、しかし、データはローカルなプロセス間通信に使おうというものです。元々はUNIXドメインソケットと呼んでいたのですが、Posix ではUNIXに依存しないのでローカルIPC という呼び方をしています。しかし、その呼ばれ方はあまりにも知られていないので、カッコつきで(UNIXドメインソケット)と並べて置きました。
しかし、データはローカルなプロセス間通信に使おうというものです。元々は
+
UNIXドメインソケットと呼んでいたのですが、Posix ではUNIXに依存しないの
+
でローカルIPC という呼び方をしています。しかし、その呼ばれ方はあまりに
+
も知られていないので、カッコつきで(UNIXドメインソケット)と並べて置きま
+
した。
+
  
  
;補足: POSIXでは「ローカルIPC」という呼び方をしますが、UNIX流では
+
;補足: POSIXでは「ローカルIPC」という呼び方をしますが、UNIX流ではUNIXドメインソケットと呼びます。
UNIXドメインソケットと呼びます。
+
  
  
socket(2)、bind(2)、accept(2)のようにTCP/IPの通信を行うやり方は、今ま
+
socket(2)、bind(2)、accept(2)のようにTCP/IPの通信を行うやり方は、今までのUNIXとはセマンティクス(意味的なもの)が違います。UNIXが、すべてを名前つきパイプのように名前空間でアクセスしようとするのに対して、TCP/IP のような通信系のやり方は、一々、IPアドレスやポート番号を指定しなければいけません。
でのUNIXとはセマンティクス(意味的なもの)が違います。UNIXが、すべてを
+
名前つきパイプのように名前空間でアクセスしようとするのに対して、TCP/IP  
+
のような通信系のやり方は、一々、IPアドレスやポート番号を指定しなければ
+
いけません。
+
  
  
156行目: 136行目:
 
  ....
 
  ....
  
ソケットをAF_LOCALで作成し、sun_familyをAF_LOCALに指定し、sun_path
+
ソケットをAF_LOCALで作成し、sun_familyをAF_LOCALに指定し、sun_path の部分にファイルパスを書きバインドすると、そのパスにファイルに見えるソケットが出来ます。こうすれば、あとのデータの送信/受信に関係するプログラムの構造はTCP/IPと同じに作れます。その面ではインターネット経由でアクセスするプログラムとローカルにアクセスするプログラムが同じ構造で作れる利点があります。
部分にファイルパスを書きバインドすると、そのパスにファイルに見えるソケッ
+
トが出来ます。こうすれば、あとのデータの送信/受信に関係するプログラム
+
の構造はTCP/IPと同じに作れます。その面ではインターネット経由でアクセス
+
するプログラムとローカルにアクセスするプログラムが同じ構造で作れる利点
+
があります。
+
  
  
168行目: 143行目:
  
  
これはログデーモンがオープンしているソケットです。しかしながら、パス名
+
これはログデーモンがオープンしているソケットです。しかしながら、パス名で見えていても、ファイルではないので、通常のファイルを扱うコマンドでアクセスしてもエラーになります。
で見えていても、ファイルではないので、通常のファイルを扱うコマンドでア
+
クセスしてもエラーになります。
+
  
  
180行目: 153行目:
  
  
これらはIPスタックを経由しません。IPは複数の独立したホストがあり、ネッ
+
これらはIPスタックを経由しません。IPは複数の独立したホストがあり、ネットワーク構築された世界をIPパケットが中継されていくモデルです。そのためにIPパケットを処理するためには、そのための処理がなされます。一方、UNIXドメインソケットには、そんな付加する情報をつけたり処理したりする必要はありません。よって高速に処理することが可能になります。
トワーク構築された世界をIPパケットが中継されていくモデルです。そのため
+
 
にIPパケットを処理するためには、そのための処理がなされます。一方、UNIX
+
 
ドメインソケットには、そんな付加する情報をつけたり処理したりする必要は
+
== 脚注 ==
ありません。よって高速に処理することが可能になります。
+
 
 +
<references/>
 +
 
 +
----
 +
[[目次]]へ
 +
 
 +
 
 +
このページへのショートURL:  http://uc2.h2np.net/i/25.html

2018年12月15日 (土) 18:03時点における版

IPCとは

プロセス実行中に他のプロセスと通信を行うための機構を考えます。通信ということでは2つの方法を挙げることができます。


  • ローカルマシン内(もちろん動いているカーネルは1つという前提)で動作しているプロセス間での通信。
  • ネットワークを経由して通信するネットワーク通信。


本章では前者のローカルマシン内での通信を取り上げます。もちろんローカルマシン内で動作するプロセス同士でもネットワーク経由と同じようにTCP/IPを使って通信できますが、本章のプロセス間通信の説明からはTCP/IPは除いておきます。


ここでのプロセス通信(InterProcess Communication / IPC )[1]とは、名前つきパイプ(named pipe)、pipe、UNIXドメインソケット(ローカルIPC)、 セマフォー[2]やあるいはシェアードメモリなどを指しています。これらにより高速にプロセス間でデータをやりとりするためのメカニズムと捉えます。Linuxでは、 System Vで使われていたプロセス間通信の機能、4.2BSDで採り入れられたソケット、名前つきパイプが使えます。


補足
単一カーネル内ではIPのルーティング機能などの不必要な情報の付加や処理を行わずに済むので、その点から「高速にデータをやりとり」と書いていますが、経験的には、実際の速度差は実装によってずいぶん違うので、一概にどれぐらい違うかは簡単にはいえません。

System V IPC

プロセス間通信の機能というと、System Vで使われていたプロセス間通信の機能(System V IPC)のセマフォー[3](semaphore)、メッセージキュー(message queues)、シェアードメモリ(shared memory)が有名です。


ソフトウェアの世界では、複数のプロセスが同じ資源の競合を避けるために、使われる機能で、たとえば複数のプロセスが同時にファイルを書き込みするタイミングが同じになってしまわないように、セマフォを使って待ちます。 セマフォは(ファイルのロックなどを使うよりも)高速に処理できるので、たとえばデータベースのようなアプリケーションでの処理のロックなどに使われています。 しかし、同様な処理はmmapを使っても可能ですので、今日ではセマフォがなくては実装ができない、というわけではありません。むしろ、互換性のために残していると考えた方が良いでしょう。また今日ではSystem V IPCは、相対的に「重い」処理と考えられています。 一方、POSIX IPC はマルチスレッドで安全であり、かつ、System V IPCより軽量なのでPOSIX IPCの利用が推奨されています。[4]


semget (2)           - セマフォーの獲得
semctl (2)           - セマフォーの制御
semop (2)            - セマフォーの設定


System V IPCを使ってのメッセージキューは古いアプリケーションを動かすための互換性のために残されているようなもと考えても良いレベルになって来ています。今日では新規のプログラムに使うような場面を見かけたことがありません。最近ではメッセージキューを使う所を名前つきパイプで済ますことができます。シェアードメモリもmmapが使えます。


Linuxのカーネルが2.6以降ではPOSIX IPCが使えるようになりました。新しくプログラムを作る場合で、メッセージキューなどを使いたい時はSystem V IPCではなくPOSIX IPCを使うべきでしょう。

POSIX IPC

TBD

名前つきパイプ

その前にパイプを説明しましょう。コマンドラインでのシェルが持つパイプは、 前のコマンドの標準出力を後ろのコマンドの標準入力にするというものです。 使い勝手は、まるっきりファイルです。


現在のディレクトリにあるファイル数をカウントする
% ls  | wc  


このようなプロセス間で一方向に書き出し、読み込みをするプログラムを書く 時は、UNIXの初期からあるシステムコールとしてpipe(2)を使って実現します。 pipe(2) は、プロセス中で2つの要素を持つファイルデスクリプタ配列に対し て、1つは書き込み、もう1つは読み込みのディスクリプタを与えるというもの です。このペアを作っておき、プロセスがフォークすると、1つのプロセス側 は書き込み、もう一つのプロセス側は読み込みができるようになります。もち ろん一方向にしかデータは流れません。


さて、名前つきパイプは、それまでのプロセスがフォークして資源を継承する しかできない一方向に流れるパイプとは違い、2つの完全に独立に存在してい るプロセス間でデータをやり取りするために作られたものです。


FIFO(First-In-First-Out)である名前つきパイプを作ります。これはファイル のように名前でアクセスできるFIFOの性質を持った双方向パイプを作ります。


まずコマンド mkfifo で名前つきパイプのファイルを作ります。ファイルといっ てもアクセスのために名前だけあって実態はパイプです。 ls -l で見ると先 頭がpがあるので、名前つきパイプであることがわかります。あとls -Fとして みると、npの後ろに"|"がついて出力されます。これは名前つきパイプ(FIFO) のファイルであるという意味です。


$ mkfifo np
$ ls -l np
prw-r--r--    1 hironobu hironobu        0 Dec 16 21:58 np
$ ls -F np
np|


この状態で2つのshellウインドウを開いてみてください。一つはnpを読む、も う一つではnpに書き込むことをしてみます。


shellウインドウ1
$ cat np
abcdef <-- 表示される
123456 <-- 表示される
$      <-- 終了する
shellウインドウ2
$ cat > np
abcdef <--入力
123456 <--入力
^D     <-- ^Dで終了
$ 


ここでは判りやすいように一方向にデータを送っている例を出していますが、 このようにファイル名でアクセスするようにしてプロセス間の通信が出来ると いうのは、実にUNIXらしいやり方です。プログラム中から名前つきパイプを作 る時はユーザ関数 mkfifo(3)で作れます。


UNIXドメインソケット (ローカルIPC)

これはTCP/IPネットワーク接続の機能のインタフェースと同じものを用意して、しかし、データはローカルなプロセス間通信に使おうというものです。元々はUNIXドメインソケットと呼んでいたのですが、Posix ではUNIXに依存しないのでローカルIPC という呼び方をしています。しかし、その呼ばれ方はあまりにも知られていないので、カッコつきで(UNIXドメインソケット)と並べて置きました。


補足
POSIXでは「ローカルIPC」という呼び方をしますが、UNIX流ではUNIXドメインソケットと呼びます。


socket(2)、bind(2)、accept(2)のようにTCP/IPの通信を行うやり方は、今までのUNIXとはセマンティクス(意味的なもの)が違います。UNIXが、すべてを名前つきパイプのように名前空間でアクセスしようとするのに対して、TCP/IP のような通信系のやり方は、一々、IPアドレスやポート番号を指定しなければいけません。


int sockfd;
struct sockaddr_un addr;
...
sockfd=socket(AF_LOCAL, SOCKET_STREAM,0);
...
addr.sun_family = AF_LOCAL;
strcpy(addr.sun_path, "/tmp/mysocket");
bind(sockfd,&addr,SUN_LEN(addr));
....

ソケットをAF_LOCALで作成し、sun_familyをAF_LOCALに指定し、sun_path の部分にファイルパスを書きバインドすると、そのパスにファイルに見えるソケットが出来ます。こうすれば、あとのデータの送信/受信に関係するプログラムの構造はTCP/IPと同じに作れます。その面ではインターネット経由でアクセスするプログラムとローカルにアクセスするプログラムが同じ構造で作れる利点があります。


$ ls -lF /dev/log
srw-rw-rw-    1 root     root            0 Aug 23 14:13 /dev/log=


これはログデーモンがオープンしているソケットです。しかしながら、パス名で見えていても、ファイルではないので、通常のファイルを扱うコマンドでアクセスしてもエラーになります。


かな漢字サーバWnnのソケットをcatで見てみる
$ ls -lF /tmp/jd_sockV4 
srwxr-xr-x    1 wnn      nogroup         0 Sep 21 13:48 /tmp/jd_sockV4=
$ cat /tmp/jd_sockV4 
cat: /tmp/jd_sockV4: No such device or address


これらはIPスタックを経由しません。IPは複数の独立したホストがあり、ネットワーク構築された世界をIPパケットが中継されていくモデルです。そのためにIPパケットを処理するためには、そのための処理がなされます。一方、UNIXドメインソケットには、そんな付加する情報をつけたり処理したりする必要はありません。よって高速に処理することが可能になります。


脚注

  1. LinuxのIPCについては次の発表スライドが参考になります。 Michael Kerrisk, "An introduction to Linux IPC", linux.conf.au 2013 http://man7.org/conf/lca2013/IPC_Overview-LCA-2013-printable.pdf
  2. Linuxのセマフォーに関しては次のWebサイトが詳しい。 http://www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html
  3. セマフォーとは、元々は列車運行で列車が単線の区間に入ることを許されているか、あるいは待つのかを示す信号機なのだそうです。
  4. IBMのdeveloper worksのサイトの中にある "System V のセマフォー API を使用して POSIX のセマフォー API を実装する" の本文中に「POSIX のセマフォーは System V のセマフォーよりもはるかに軽量」という記述も存在する。

目次


このページへのショートURL: http://uc2.h2np.net/i/25.html