プロセスアドレス空間
プロセスは、それぞれ独立したアドレス空間を持ち、その中で実行されます。
- ユーザーモードで動作するプロセスは、独自のスタック領域、データ領域、コード領域を参照します。
- カーネルモードで動作する場合、プロセスはカーネルのデータ領域やコード領域にアクセスし、さらにカーネル専用のスタックを使用します。
カーネルは再入可能(reentrant)であるため、複数のプロセスが同時にカーネルコードを実行することができます。このとき、各プロセスには専用のカーネルスタックが割り当てられ、プロセスの切り替え時(コンテキストスイッチ時)に適切に管理されます。
アドレス空間の共有
通常、各プロセスは独立したアドレス空間を持ちますが、一部の領域をプロセス間で共有することもあります。共有の目的は主に以下の2つです。
-
メモリの節約
- 同じプログラムを複数のプロセスが実行する場合、プログラムのコード(命令部分)は一度だけメモリにロードされ、すべてのプロセスが共有します。
- ただし、データ領域(変数など)は各プロセスごとに独立して確保されるため、他のプロセスのデータを変更することはできません。
- このような仕組みにより、不要なメモリ消費を抑え、効率的にメモリを使用できます。
-
プロセス間通信(IPC)
- プロセス同士がデータをやり取りするために、特定のメモリ領域を共有することがあります。
- これにより、メッセージキューやパイプなどの従来のIPC手法よりも高速なデータ共有が可能になります。
プロセス間でのメモリ共有には、主に 共有メモリ(Shared Memory) と メモリマッピング(Memory Mapping) の2つの手法があります。
共有メモリ(Shared Memory)
共有メモリは、複数のプロセスが同じ物理メモリ領域を同時に参照できる仕組みです。
-
System V 共有メモリ(SysV SHM)
- System V IPC(Interprocess Communication)の一環として提供されており、Linuxでも利用できます。
- shmget() で共有メモリ領域を作成し、shmat() で各プロセスがそれをマウントすることで、同じメモリ領域を共有できます。
- shmdt() でデタッチし、最後のプロセスが shmctl() を使って解放することで、共有メモリ領域が削除されます。
-
POSIX 共有メモリ(POSIX SHM)
- shm_open() や mmap() を用いて、ファイルシステム上の一部を共有メモリとして利用する方法。
- System V よりもシンプルで、ファイルベースの管理が可能なため、モダンなアプリケーションではPOSIX SHMが推奨されることが多い。
共有メモリのメリットとデメリット
メリット
- 非常に高速(カーネルを介さず、直接メモリ操作ができる)。
- 大容量データのやり取りに向いている。
デメリット
- 共有メモリのライフサイクル管理が難しい(不要になったときの解放を適切に行わないとメモリリークの原因になる)。
- 複数のプロセスが同じデータを更新するため、適切な同期(ミューテックスやセマフォ)が必要。
メモリマッピング(Memory Mapping)
メモリマッピングは、ファイルやデバイス上のデータをプロセスの仮想アドレス空間にマッピングする技術です。Linuxでは mmap() システムコールによって実現されます。
- ファイルをメモリ上にマッピングすることで、read() や write() のようなシステムコールを使わずに、メモリ操作だけでデータを読み書きできる。
- 同じファイルを複数のプロセスが mmap() すると、物理メモリ上でデータが共有される。
- これにより、ディスクI/Oの回数を削減し、パフォーマンスを向上させることが可能。
mmap() の使い方
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
int fd = open("example.txt", O_RDWR);
void *mapped_mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
- MAP_SHARED を指定すると、マッピングされたメモリ領域は他のプロセスと共有可能。
- MAP_PRIVATE を指定すると、プロセスごとに独立したコピーが作成される(書き込み時にコピーが発生する、Copy-on-Write)。
メモリマッピングのメリットとデメリット
メリット
- ファイルをメモリのように扱えるため、ディスクI/Oを減らし高速化できる。
- 複数のプロセス間でファイルの内容を簡単に共有できる。
- OSが必要に応じてメモリを管理するため、効率的なメモリ使用が可能。
デメリット
- 共有メモリと同様に、データの整合性を保つために適切な同期処理が必要。
- mmap() の使用にはページアライメントなどの制約があるため、プログラム設計時に考慮が必要。
まとめ
共有メモリ(Shared Memory) は、プロセス間で直接メモリを共有する方法。特に大量のデータを高速に共有する用途に適している。
メモリマッピング(Memory Mapping) は、ファイルやデバイスをプロセスのアドレス空間にマッピングし、効率的にデータを共有・操作する手法。
どちらもプロセス間通信の手段として有用ですが、用途によって適切な方法を選ぶことが重要です。
免責事項
本記事は、筆者の理解に基づいて執筆したものです。正確性には十分配慮していますが、内容の誤りや最新の情報と異なる可能性があります。
本記事の内容を参考にしたことによるいかなる損害についても、筆者は責任を負いかねますのでご了承ください。
正確な情報や書籍に書かれている根拠等はサポートしませんので、ご自身で公式ドキュメントをお調べください。
よって、この内容をAIの学習データに活用することはおすすめしません。