
コンピュータ科学において、共有メモリとは、複数のプログラムが同時にアクセスできるメモリであり、プログラム間の通信を可能にしたり、冗長なコピーを回避したりすることを目的としています。共有メモリは、プログラム間でデータを効率的に受け渡す手段です。状況によっては、プログラムは単一のプロセッサ上で実行される場合もあれば、複数の独立したプロセッサ上で実行される場合もあります。
単一のプログラム内部、例えば複数のスレッド間での通信にメモリを使用することも、共有メモリと呼ばれます。

コンピュータハードウェアにおいて、共有メモリとは、マルチプロセッサコンピュータシステム内の複数の異なる中央処理装置(CPU)からアクセスできる、 (通常は大きな)ランダムアクセスメモリ(RAM)のブロックを指します。
共有メモリシステムでは、以下が使用される場合があります。[ 1 ]
共有メモリシステムは、すべてのプロセッサが単一のデータビューを共有し、プロセッサ間の通信速度が同じメモリ位置へのアクセス速度と同程度であるため、比較的簡単にプログラミングできます。共有メモリシステムの問題点は、多くのCPUがメモリへの高速アクセスを必要とし、メモリをキャッシュする可能性が高いことです。これには2つの複雑な問題があります。
クロスバースイッチ、オメガネットワーク、ハイパートランスポート、フロントサイドバスなどの技術を用いることで、ボトルネックの影響を軽減できる。
異種システムアーキテクチャ( CPUやGPUなど、異なる種類のプロセッサを共有メモリで統合したプロセッサアーキテクチャ)の場合、 CPUのメモリ管理ユニット(MMU)とGPUの入出力メモリ管理ユニット(IOMMU)は、共通のアドレス空間など、特定の特性を共有する必要があります。
コンピュータソフトウェアでは、共有メモリは
両方のプロセスが通常の作業メモリのように共有メモリ領域にアクセスできるため、これは非常に高速な通信方法です(名前付きパイプ、Unixドメインソケット、CORBAなどの他のIPCメカニズムとは対照的です)。一方で、通信するプロセスが同じマシン上で実行されている必要がある(他のIPC方式では、インターネットドメインソケットのみがコンピュータネットワークを使用できますが、Unixドメインソケットは使用できません)、メモリを共有するプロセスが別々のCPU上で実行されていて、基盤となるアーキテクチャがキャッシュコヒーレンシを持たない場合に問題が発生しないように注意する必要があるなど、拡張性は劣ります。
共有メモリによるIPCは、例えばUnixシステム上でアプリケーションとXサーバー間で画像を転送する場合や、 WindowsのCOMライブラリでCoMarshalInterThreadInterfaceInStreamによって返されるIStreamオブジェクト内で使用されます。
動的ライブラリは通常、メモリ上に一度だけ保持され、複数のプロセスにマッピングされます。個々のプロセスに合わせてカスタマイズする必要のあるページ(シンボルの解決方法が異なるため)のみが複製されます。通常、コピーオンライトと呼ばれるメカニズムによって、書き込みが試行されたときにページが透過的にコピーされ、プライベートコピーへの書き込みが成功します。
複数のアドレス空間を持つオペレーティングシステムと比較して、メモリ共有、特に共有プロシージャやポインタベースの構造の共有は、単一アドレス空間のオペレーティングシステムの方が簡単です。[ 2 ]
POSIX は、共有メモリを使用するための標準化されたAPI 、 POSIX Shared Memoryshm_openを提供します。これは、 sys/mman.h の関数を使用します。 [ 3 ] POSIX プロセス間通信 (POSIX:XSI 拡張の一部) には、共有メモリ関数shmat、、shmctlおよびshmdtが含まれますshmget。[ 4 ] [ 5 ] Unix System V も共有メモリ用の API を提供します。これは、sys/shm.h の shmget を使用します。BSD システムは、複数のプロセスで使用できる「匿名マップドメモリ」を提供します。
によって作成された共有メモリはshm_open永続的です。プロセスによって明示的に削除されるまでシステムに残ります。この欠点は、プロセスがクラッシュして共有メモリをクリーンアップできなかった場合、システムがシャットダウンするまで残ってしまうことです。この制限は、と呼ばれる Android 固有の実装には存在しませんashmem。[ 6 ]
POSIXはmmap、ファイルをメモリにマッピングするためのAPIも提供しています。マッピングは共有可能であり、ファイルのコンテンツを共有メモリとして使用できます。
2.6カーネル以降に基づくLinuxディストリビューションでは、/dev/shmがRAMディスクの形式で共有メモリとして提供されます。より具体的には、メモリに格納されるワールド書き込み可能なディレクトリ(システムのすべてのユーザーがファイルを作成できるディレクトリ)として提供されます。RedHatとDebianベースのディストリビューションはどちらもデフォルトでこれを含んでいます。このタイプのRAMディスクのサポートは、カーネル設定ファイル内で完全にオプションです。[ 7 ]
Windowsでは、関数を使用しCreateFileMappingてMapViewOfFileファイルの領域を複数のプロセスのメモリにマッピングできます。[ 8 ]
一部のC++ライブラリは、共有メモリ機能への移植性とオブジェクト指向性を備えたアクセスを提供します。たとえば、BoostにはBoost.Interprocess C++ライブラリ[ 9 ]が含まれており、QtはQSharedMemoryクラスを提供しています[ 10 ] 。
POSIXバインディングを持つプログラミング言語(例えばC/C++)では、オペレーティングシステムが提供する関数を呼び出すことで共有メモリ領域を作成およびアクセスできます。他のプログラミング言語でも、同様の効果を得るためにこれらのオペレーティングシステムの機能を使用する独自の方法がある場合があります。たとえば、PHPはPOSIX関数と同様に、共有メモリを作成するためのAPIを提供しています。[ 11 ]
プロセス間通信(IPC)はPOSIX:XSI拡張の一部であり、Unix System Vのプロセス間通信に由来する。