メッセージキューと共有メモリの違いについての記事をたくさん読みました。しかし、どちらが優れたパフォーマンスを達成するのに適しているかはまだ明確ではありません。
共有メモリのように、キューよりも優れていると思われますが、同期する場合のパフォーマンスの問題もあります。
共有メモリとメッセージキューの両方を使用して、プロセス間で情報を交換できます。違いは、howの使用方法にあります。
共有メモリはまさにあなたが思うことです:それは複数のプロセスによって読み書きできるストレージの領域です。固有の同期は提供されません。言い換えれば、あるプロセスが別のプロセスのデータを破壊しないようにするのはプログラマーの責任です。ただし、スループットの点では効率的です。読み取りと書き込みは比較的高速な操作です。
メッセージキューは一方向のパイプです。1つのプロセスがキューに書き込み、別のプロセスがデータの終わりの状態が発生するまで、書き込まれた順序でデータを読み取ります。キューが作成されると、メッセージサイズ(メッセージあたりのバイト数、通常はかなり小さい)とキューの長さ(保留中のメッセージの最大数)が設定されます。各読み取り/書き込み操作は通常単一のメッセージであるため、アクセスは共有メモリよりも低速です。ただし、キューは、各操作がメッセージ全体を正常に処理するか、キューを変更せずに失敗することを保証します。したがって、ライターは部分的なメッセージのみを書き込んだ後に失敗することはなく、リーダーは完全なメッセージを取得するか、まったく取得しません。
あるプロセスが共有メモリに書き込み、別のプロセスが共有メモリから読み取る可能性のある競合状態を考慮して共有メモリを使用する場合は、注意が必要です。前者を使用することには関連するリスクがあります。2つのプロセスがそれを使用していると仮定します。1つは書き込み用、もう1つは読み取り用、書き込み中のプロセスは異常な状態のために停止し、読み取りプロセスはハングまたはクラッシュする可能性があります。
共有メモリは、キューよりも高速(オーバーヘッドが少なく、大量のデータが渡される)と見なすことができます。ただし、一方で、キューは、データ量が少なく、高いオーバーヘッド(キューを永続的にするための設定など)を必要とします。
共有メモリの責任は、スレッドセーフにするために同期を実装する必要があることです。 IPCの Beej による優れた記事をご覧ください。
キューを使用する場合、それらはスレッドセーフであり、それだけでなく、結果に関係なくメッセージがキューに保持されます。1つのプロセスがキューに(メッセージの形式で)書き込むときに、2つのプロセスがキューを使用していると仮定します。そこから読み取ろうとしている他のプロセスは、そのような状況でのクラッシュまたは異常な状態のために死ぬか、強制終了されます。そのメッセージはまだ存在します。再起動された場合、他のプロセスはキューから読み取ることができます。 。
それが2つの違いです。
メッセージキューには固有の同期オーバーヘッドがあり、パフォーマンスを犠牲にして安全性が保証されます。共有メモリには保護手段がありません。2つのスレッドが同時にアクセスすると、スレッドの安全性を自分で保証しない限り、競合する(一貫性のないデータを書き込む)可能性があります。マイナーエラーが許可されている場合(たとえば、データがアナログ出力に送られ、ある程度のノイズが許容される場合)、これは重要ではない可能性があるため、エラーチェックを完全にスキップして、非常に高いパフォーマンスゲインで「十分に良い」アプローチを実行できます。また、共有メモリを使用すると、大きなデータを交換したり、メモリストレージを節約する複数のアプリに共通のデータを共通かつ永続的に保存したりできます。メッセージキューはスループットを低下させるためのものです。たとえば、共有メモリへのアクセスを保護するためにメッセージキューを利用できます。
メッセージキューと共有メモリは、2つのプロセス間でデータを共有するために使用されます。メッセージキューでは、データを特定の形式で共有する必要があります。両方のプロセスがこれに同意し、メッセージを共有する必要があります。カーネルを使用すると、メッセージ全体を読み取ることも、メッセージキューに対して何も読み取らないこともできます。ただし、共有メモリでは、セグメントの一部を2つのプロセス間で共有する必要があります。どちらも同期技術を実行し、プロセス間でデータを共有できます。他のプロセスと共有するためにデータをコピーする必要がないため、共有メモリの方が高速です。