【Linux カーネル: OS 入門8】IPC (プロセス間通信)

IPC (Inter Process Communication)IPC とは、プロセス間で通信 (データをやりとり) する仕組みです。

本記事では、以下の IPC について説明します。

IPC の種類特徴具体例
パイプ (匿名パイプ)単方向・プロセスを forkシェルのパイプ (|)
名前付きパイプ (FIFO)ファイルシステムを使うパイプ
権限を持つ全プロセスで利用可
mkfifo コマンド
シグナル割り込み処理Ctrl + C (SIGINT)
メッセージキューメッセージ単位で読み書き
非同期通信可能
専用のソフトウェアを使う場合も
(例:Apache Kafka)
セマフォ/mutex排他制御に使用データベース
(mutex でロックを実現)
共有メモリ高速
排他制御のためにセマフォを併用
データベース
Non-persisted
メモリマップドファイル
共有メモリの作成に利用
メモリを直接読み書き
共有メモリの作成に利用
ソケット
(インターネットソケット)
ネットワーク越しで通信可能
双方性・プロセス fork 不要
TCP/UDP 通信
UNIX ドメインソケットローカル通信のみ
ソケットより早い
システムログの /dev/log
Web と AP サーバー間の通信
https://en.wikipedia.org/wiki/Inter-process_communication
Linux カーネルの機能
スポンサーリンク

各 IPC の詳細

パイプ (Anonymous pipe)

パイプとは、プロセスAの出力をプロセスBの入力に繋げる仕組みです。

パイプの利用例は、シェルのパイプ (|) です。

例えば「cat test.txt | grep abc」の場合、親プロセスの cat 出力が pipe0 を経由して、子プロセス grep の入力となります。

https://www.baeldung.com/cs/pipes-vs-sockets

名前付きパイプ (Named pipe/FIFO)

名前付きパイプとは、ファイルシステムで名前をつけるパイプです。

名前付きパイプの利用例は、mkfifo コマンドです。

名前付きパイプの作成 (mkfifo コマンド)

名前付きパイプは、以下のコマンドで作成可能です。

mkfifo my_pipe

ファイルの種類が名前付きパイプ (先頭のシンボルが "p") であることが確認できます。

ls -l my_pipe
prw-rw-r-- 1 ec2-user ec2-user 0  1月  6 06:44 my_pipe

名前付きパイプを使ったプロセス間の通信は以下のとおりです。

cat my_pipe

別の端末から、以下のコマンドを実行します。

echo test > my_pipe

cat プロセス側の端末を見ると、echo プロセスから送信されたデータ ("test") を確認できます。

名前付きパイプの特徴

ファイルシステムを使うため、以下の特徴を持ちます。

シグナル

シグナルとは、プロセスに対して送る番号です。
プロセスは、通常の処理に割り込んで、受け取ったシグナルに対応する処理を行います。

シグナルの利用例は、プロセスを終了するショートカットキー Ctrl + C (SIGINT) です。

シグナル一覧

代表的なシグナルは以下です。(全てのシグナル一覧はこちら)

ID (番号)シグナル動作※説明 (シグナルの意味)
1SIGHUP終了端末の終了/プロセスの死
2SIGINT終了キーボードからの割り込みシグナル
3SIGQUITコアキーボードによる中止
9SIGKILL終了Kill シグナル
17SIGCHLD無視プロセスの一時停止 (stop) または終了
18SIGCONT続き一時停止 (stop) からの再開
19SIGSTOP停止プロセスの一時停止

※「動作」は、デフォルトで以下の動作となります。
なお、SIGKILL と SIGSTOP 以外はデフォルトから変更可能です。

デフォルトの動作説明
再開プロセス終了
無視シグナルの無視
コアプロセス終了とコアダンプ出力
停止プロセスの一時停止
続きプロセスが停止中の場合にその実行の再開

任意のシグナルを送信 (kill コマンド)

kill コマンドを利用することで、任意のシグナルを送信可能です。

ps
  PID TTY          TIME CMD
26452 pts/0    00:00:00 ps
30812 pts/0    00:00:00 bash
kill -1 30812
Connection to 192.0.2.1 closed.

SIGHUP により、端末が終了しました。

メッセージキュー

メッセージキューとは、メッセージ (順序付き文字列) を出し入れできる仕組みです。

メッセージキューの利用例は、プロセス間で非同期に通信する際のバッファです。

大規模なメッセージキューを必要とする場合は、専用のソフトウェア (Apache Kafka など) を利用します。

メッセージキューの確認 (ipcs コマンド)

メッセージキューは、ipcs コマンドで確認可能です。

ipcs
------ メッセージキュー --------
キー     msqid      所有者  権限     使用済みバイト数 メッセージ

------ 共有メモリセグメント --------
キー     shmid      所有者  権限     バイト  nattch     状態      

------ セマフォ配列 --------
キー     semid      所有者  権限     nsems  

セマフォ/mutex

セマフォ/mutexとは、利用可能なリソース (CPU とか) の数を管理する仕組みです。

セマフォ/mutex の利用例は、データベースリソース制限ロックです。

セマフォの詳細

セマフォのルールは以下の4つです。

  1. セマフォの値をリソースの数と同じにします
  2. リソースを使用すると、セマフォの値を1減らします
  3. セマフォの値 (利用可能なリソース) が0でプロセスを実行する場合、リソースの解放待ちとなる
  4. リソースの使用が終わると、セマフォの値を1増やします

待ち状態のプロセスを、実行状態にするためには、コンテキストスイッチが発生します。

mutex の詳細

mutex は、値が0と1しかないセマフォです。

また、スピンロック (CPU で無意味な処理) を利用して、プロセスを実行状態のままにしながらリソースの解放待ちをします。そのため、コンテキストスイッチが発生しない代わりに、CPU を消費し続けます。

セマフォと mutex の違いをまとめると以下のとおりです。

セマフォmutex
利用用途しばらくリソースが解放されない時すぐにリソースが解放される時
コンテキストスイッチあり (待ち状態から復帰に時間がかかる)なし
スピンロックなしあり (CPU に負荷をかける)
とりうる値複数0と1 (使用/未使用)

セマフォの確認方法 (ipcs コマンド)

セマフォ配列は、ipcs コマンドで確認可能です。

ipcs
------ メッセージキュー --------
キー     msqid      所有者  権限     使用済みバイト数 メッセージ

------ 共有メモリセグメント --------
キー     shmid      所有者  権限     バイト  nattch     状態      

------ セマフォ配列 --------
キー     semid      所有者  権限     nsems  

共有メモリ

共有メモリとは、複数のプロセスが共有するメモリ空間を利用してデータを通信する仕組みです。

共有メモリの利用例は、データベースキャッシュや WAL バッファです。

共有メモリの特徴

共有メモリは、他の IPC と異なり、カーネルを経由しないため高速で動作します。
(IPC ベンチマークの結果はこちら)

共有メモリの欠点

共有メモリのアクセスにカーネルを経由しないため、排他制御を実装する必要があります。

排他制御でリソースを利用中かどうかを判断するために、セマフォ/mutex を利用します。

共有メモリの確認 (ipcs コマンド)

共有メモリは、ipcs コマンドで確認可能です。

ipcs
------ メッセージキュー --------
キー     msqid      所有者  権限     使用済みバイト数 メッセージ

------ 共有メモリセグメント --------
キー     shmid      所有者  権限     バイト  nattch     状態      

------ セマフォ配列 --------
キー     semid      所有者  権限     nsems  

Non-persisted メモリマップドファイル

Non-persisted メモリマップドファイルとは、ファイル仮想メモリにマッピングしてプロセス間通信をする仕組みです。

Non-persisted メモリマップドファイルの利用例は、共有メモリを作成です。

なお、Non-persisted メモリマップドファイルは永続化されていません。(ストレージファイルが関連づけられていません)

ソケット (インターネットソケット)

ソケット (インターネットソケット) とは、ネットワーク越しで通信可能な仕組みです。

ソケットの利用例は、TCP/UDP で通信です。

一般的にソケットは、<IP アドレス> と <ポート番号> で指定します。

ソケットの確認方法 (netstat コマンド)

Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0    200 ip-192-0-2-1:ssh 198.51.100.1:60000 ESTABLISHED
tcp        0      0 ip-192-0-2-1:50000 198.51.100.1:https     ESTABLISHED

UNIX ドメインソケット

UNIX ドメインソケットとは、単一マシン上 (=インターネットを介さない) で通信する仕組みです。

UNIX ドメインソケットの利用例は、「システムログの /dev/log」や、「Web サーバーAP サーバーの通信」です。

一般的に UNIX ドメインソケットは、ファイルパスで指定します。

UNIX ドメインソケットの確認方法 (netstat コマンド)

Proto RefCnt Flags       Type       State         I-Node   Path
unix  3      [ ]         DGRAM                    10000    /run/systemd/notify
unix  6      [ ]         DGRAM                    10001    /run/systemd/journal/socket
スポンサーリンク

関連情報

Linux カーネルの機能

参考資料

Inter Process Communication Tutorial
Inter Process Communication Tutorial - Inter Process Communication (IPC) refers to a mechanism, where the operating systems allow various processes to communica...
Inter-process communication - Wikipedia
プロセス間通信の種類 - Qiita
Introduction of CommunicationagendaWHOAMIWHAT IS IPCPIPESIGNALSEMAPHOREMESSAGESHARED MEMORYSOCKE…
https://docs.oracle.com/cd/E19253-01/819-0392/svipc-38596/index.html