知識マップ: 共有メモリの落とし穴と実務ベストプラクティス
記事「共有メモリの落とし穴と実務ベストプラクティス」の主張を、概念と関係(エッジ)に分解した知識グラフの全体です。各関係には根拠・確認日・確度が付いています。
共有メモリはWindowsのCreateFileMapping/MapViewOfFileやPOSIXのshm_open/mmapを使い、同じ物理ページを複数プロセスから見せる仕組みだが、同期そのものではないため、同期なしで複数フィールドを読み書きするとwriterの書き込み途中を読んでしまう事故が起きうる。この事故はSPSCリングバッファやダブルバッファによるcommitプロトコルで防ぎ、生ポインタやHANDLEなどprocess-local資源はそのまま置けないためオフセット参照に置き換え、control planeとdata planeを分離して通知は別チャネルへ逃がすことが推奨される。加えて、ABIの固定、作成者だけが初期化する運用による初期化レースの回避、Windowsのabandoned mutexやPOSIXのrobust mutexを使ったクラッシュ復旧設計、名前空間・権限の構成、世代ごとのサイズ固定が、事故率を下げる実務上の要点になる。
flowchart LR
accTitle: 共有メモリの落とし穴とベストプラクティスの知識マップ
accDescr: 共有メモリがバイト列を共有するだけで同期そのものではないこと、途中状態の読み取りや初期化レース・クラッシュ復旧・ABI不一致・false sharingといった落とし穴、control planeとdata planeの分離やSPSCリングバッファ・ダブルバッファ・オフセット参照といった対策の関係を示す図
shared_memory["共有メモリ"]
windows_createfilemapping["CreateFileMapping/MapViewOfFile"]
posix_shm_open["shm_open/ftruncate/mmap"]
memory_mapped_file["ファイルマッピング(メモリマップトファイル)"]
torn_read["途中状態の読み取り"]
spsc_ring_buffer["SPSCリングバッファ"]
double_buffering_commit["ダブルバッファによるcommitプロトコル"]
control_plane_data_plane_separation["control planeとdata planeの分離"]
shared_memory_header["共有メモリの固定ヘッダ"]
offset_reference["オフセット参照"]
process_local_resource["process-localな資源"]
shared_memory_abi["共有メモリのABI設計"]
initialization_race["初期化レース"]
creator_joiner_initialization["creatorだけが初期化する運用"]
crash_recovery_design["クラッシュ復旧設計"]
abandoned_mutex["abandonedになったmutex(Windows)"]
robust_mutex["robust mutex(POSIX)"]
false_sharing["false sharingとキャッシュライン競合"]
shared_memory_namespace_permission["名前空間と権限(Global/Local)"]
fixed_generation_sizing["世代ごとのサイズ固定運用"]
remote_machine_sharing["他マシンとの共有"]
notification_channel_separation["通知を別チャネルへ逃がす設計"]
busy_loop_polling["busy loopによるポーリング通知"]
named_pipe["名前付きパイプ"]
shared_memory -.->|"利用する"| windows_createfilemapping
shared_memory -.->|"利用する"| posix_shm_open
windows_createfilemapping -->|"利用する"| memory_mapped_file
shared_memory -.->|"原因になり得る"| torn_read
spsc_ring_buffer -.->|"防止する"| torn_read
double_buffering_commit -.->|"防止する"| torn_read
control_plane_data_plane_separation -->|"推奨される対応"| shared_memory
shared_memory_header -->|"推奨される対応"| shared_memory
offset_reference -->|"推奨される対応"| shared_memory
process_local_resource -->|"両立しない"| shared_memory
shared_memory -->|"前提とする"| shared_memory_abi
shared_memory -.->|"原因になり得る"| initialization_race
creator_joiner_initialization -->|"防止する"| initialization_race
crash_recovery_design -->|"推奨される対応"| shared_memory
crash_recovery_design -.->|"利用する"| abandoned_mutex
crash_recovery_design -.->|"利用する"| robust_mutex
shared_memory -.->|"原因になり得る"| false_sharing
shared_memory -.->|"で構成できる"| shared_memory_namespace_permission
fixed_generation_sizing -->|"推奨される対応"| shared_memory
shared_memory -->|"両立しない"| remote_machine_sharing
windows_createfilemapping -->|"両立しない"| remote_machine_sharing
notification_channel_separation -->|"推奨される対応"| shared_memory
busy_loop_polling -->|"用いるのは非推奨"| shared_memory
notification_channel_separation -.->|"利用する"| named_pipe
概念間の関係(全24件)
図と同じ関係を文章でも列挙します。表示している文と機械可読な意味データ(RDFa)は同じ要素に載っています。確度が「確立した関係」のものは直接の関係として、「条件付きの関係」のものは成立条件つきの言明(rdf:Statement)として表現しています。
- 共有メモリはCreateFileMapping/MapViewOfFileを利用します。
- 共有メモリはshm_open/ftruncate/mmapを利用します。
- CreateFileMapping/MapViewOfFileはファイルマッピング(メモリマップトファイル)を利用します。
- 共有メモリは途中状態の読み取りの原因になることがあります。
- SPSCリングバッファは途中状態の読み取りを防ぎます。
- ダブルバッファによるcommitプロトコルは途中状態の読み取りを防ぎます。
- control planeとdata planeの分離は共有メモリに対する本記事の推奨です。
- 共有メモリの固定ヘッダは共有メモリに対する本記事の推奨です。
- オフセット参照は共有メモリに対する本記事の推奨です。
- process-localな資源は共有メモリと両立しません。
- 共有メモリは共有メモリのABI設計を前提とします。
- 共有メモリは初期化レースの原因になることがあります。
- creatorだけが初期化する運用は初期化レースを防ぎます。
- クラッシュ復旧設計は共有メモリに対する本記事の推奨です。
- クラッシュ復旧設計はabandonedになったmutex(Windows)を利用します。
- クラッシュ復旧設計はrobust mutex(POSIX)を利用します。
- 共有メモリはfalse sharingとキャッシュライン競合の原因になることがあります。
- 共有メモリは名前空間と権限(Global/Local)で構成できます。
- 世代ごとのサイズ固定運用は共有メモリに対する本記事の推奨です。
- 共有メモリは他マシンとの共有と両立しません。
- CreateFileMapping/MapViewOfFileは他マシンとの共有と両立しません。
- 通知を別チャネルへ逃がす設計は共有メモリに対する本記事の推奨です。
- busy loopによるポーリング通知を共有メモリに用いることは推奨されません。
- 通知を別チャネルへ逃がす設計は名前付きパイプを利用します。
主要概念の定義
機械可読データ
このページはサイトの知識グラフ(_data/knowledge/)から自動生成されています。誤りの指摘はお問い合わせからお願いします。