共有メモリを使うときの落とし穴とベストプラクティス - 同期、可視性、寿命、ABI、セキュリティを先に整理
画像フレーム、検査結果、時系列ログ、板情報、巨大バッファ。
同一マシン内で大きなデータを低レイテンシでやり取りしたいとき、共有メモリはかなり魅力的です。
ただし、ここで少し危ないのは、共有メモリが 「速い IPC」 という顔で近づいてくることです。
実際には、共有メモリは 「コピーを減らせる代わりに、整合性の責任をアプリ側へ押し返してくる IPC」 です。
- 速い
- 柔軟
- でも protocol は自前
- 事故ると症状が派手
だいたいこの 4 点セットです。
この記事では、Windows の file mapping と POSIX shm_open / mmap を念頭に、共有メモリを実務で使うときの詰まりどころと、事故率を下げる設計 を整理します。
C/C++ でも C# の MemoryMappedFile でも、本質はほぼ同じです。1
目次
- 1. まず結論(ひとことで)
- 2. 共有メモリは何を共有して、何を共有しないのか
- 3. 共有メモリが向いている場面 / 向いていない場面
- 4. 最初に決めるべき 4 つのこと
- 4.1 control plane と data plane を分ける
- 4.2 並行モデルを絞る
- 4.3 所有者と寿命を決める
- 4.4 ABI とバージョンを決める
- 5. よくある落とし穴
- 5.1 同期しない
- 5.2 volatile で何とかしようとする
- 5.3 途中状態を読ませる
- 5.4 ポインタや複雑オブジェクトをそのまま置く
- 5.5 ABI が壊れる
- 5.6 初期化レース
- 5.7 クラッシュ復旧を考えない
- 5.8 false sharing とキャッシュライン競合
- 5.9 名前・権限・セキュリティを軽く見る
- 5.10 サイズ変更とアップグレードを雑にやる
- 5.11 通知まで全部 shared memory に押し込む
- 5.12 「これで他マシンとも共有できる」と思う
- 6. ベストプラクティス
- 6.1 control plane と data plane を分ける
- 6.2 先頭に固定ヘッダを置く
- 6.3 オフセット参照にする
- 6.4 並行モデルを絞る
- 6.5 commit protocol を明示する
- 6.6 サイズは世代ごとに固定する
- 6.7 観測可能性を入れる
- 6.8 異常系テストを先に作る
- 7. Windows と POSIX で見るポイント
- 8. まず見るチェックリスト
- 9. まとめ
- 10. 参考資料
1. まず結論(ひとことで)
先にかなり雑に、でも実務で役に立つ言い方をすると、こうです。
- 共有メモリは 同じバイト列 を複数プロセスから見せる仕組みであって、同期そのもの ではありません23
- 速いのは大きなデータ を同一マシン内でやり取りするときです。小さい制御メッセージだけなら、pipe / socket / named pipe / queue のほうが楽なことがかなり多いです
- 共有メモリでは、見えること と 安全に読めること が別問題です
volatileは設計の土台にしないほうがよいです。原子性、順序、待機 は別に考えます45- 生ポインタ、
HANDLE、file descriptor、std::string、std::vector、std::mutexをそのまま置くと、だいたい後で泣きます - 共有メモリに置くデータは、固定幅整数 + 明示的レイアウト + バージョン付きヘッダ に寄せたほうが安全です
- 先頭ヘッダに magic / version / size / state / generation / heartbeat を置くだけで、事故調査のしやすさがかなり変わります
- 共有メモリの難所は速度ではなく、初期化、寿命、復旧、権限、ABI です
- Windows なら
CreateFileMapping/OpenFileMapping/MapViewOfFile、POSIX ならshm_open/ftruncate/mmapが骨格です63 - 一番事故りにくいのは、SPSC(single-producer single-consumer)のリングバッファ か、ダブルバッファ から始めることです
要するに、共有メモリは速いけれど、雑に使うと「勝手に同期されている気がする病」にかかる。ここを避けるのが最初の勝負です。
2. 共有メモリは何を共有して、何を共有しないのか
共有メモリは、ざっくり言うと 同じ物理ページ を複数プロセスの仮想アドレス空間へマップする仕組みです。
Windows では file mapping object と view を使い、POSIX では shared memory object を mmap します。273
ここで大事なのは 2 点です。
- 共有されるのは中身のバイト列であって、仮想アドレスそのものではない
- coherent であること と 同期されていること は別
Windows のドキュメントでも、同じ file mapping object から作った view は同時点で coherent だとされています。
ただし、それは 読者が常に一貫した更新済みレコードを読める という意味ではありません。8
たとえば、
- writer が
length - つづいて
payload - つづいて
ready flag
の順に書くつもりでも、reader 側が何の同期もなく読むと、新しい length と古い payload を組み合わせて見ることがあります。
共有メモリはここを自動では直してくれません。
つまり、共有メモリが共有するのは バイト。
共有しないのは 意味、順序、完了通知、復旧方針 です。
このへんは全部、こちらで設計する必要があります。
3. 共有メモリが向いている場面 / 向いていない場面
| 場面 | 向き・不向き | 理由 |
|---|---|---|
| 同一マシン内で大きなフレームやバッファを渡す | 向いている | コピー回数を減らしやすい |
| 高頻度のセンサ値、画像、音声、板情報など | 向いている | 低レイテンシ・高スループットを狙いやすい |
| 小さいコマンドや応答だけをやり取りする | あまり向かない | 制御のための同期コストが相対的に重い |
| 他マシンとやり取りする | 向かない | 共有メモリは基本的に同一ホスト前提 |
| 異なる言語・異なるバージョンが長期共存する | 難しい | ABI とバージョニング設計が必要 |
| 永続化も必要 | 目的次第 | file-backed mapping は有力だが、永続化と IPC の責務が混ざりやすい |
実務では、制御はメッセージ系、データ本体は共有メモリ という分離がかなり強いです。
たとえば、
- UI プロセス → worker プロセスへ「次のフレームを使え」と通知するのは event / pipe / socket
- 実際のフレーム本体は共有メモリ
という構成です。
これがわりと平和です。
4. 最初に決めるべき 4 つのこと
共有メモリを設計するとき、最初に決めるべきなのは次の 4 つです。
4.1 control plane と data plane を分ける
何を shared memory に置くのかを先に決めます。
- data plane: 画像、音声、レコード列、バルクデータ
- control plane: 開始、停止、エラー、再接続、再初期化、通知
この 2 つを分けるだけで、shared memory 側の設計がかなり単純になります。
4.2 並行モデルを絞る
- SPSC: 1 producer / 1 consumer
- MPSC: 多 writer / 1 consumer
- SPMC: 1 writer / 多 reader
- MPMC: 多 writer / 多 reader
難易度は、だいたいこの順で上がります。
最初から MPMC に行くのは、かなり勇ましいです。たいてい後でメモリ順序の妖怪が出ます。
4.3 所有者と寿命を決める
- 誰が作るか
- 誰が初期化するか
- 誰が消すか
- 参加者が途中で落ちたとき、誰が回復させるか
ここが曖昧だと、起動順や再起動のたびに空気が濁ります。
4.4 ABI とバージョンを決める
- レイアウト
- 型サイズ
- alignment
- reserved 領域
- version / feature flags
- 互換性の有無
shared memory は API ではなく ABI(binary interface) の話です。
ここを雑にすると、ソース互換はあるのに実行時だけ壊れる、という嫌な事故になります。
5. よくある落とし穴
5.1 同期しない
いちばん多いのはこれです。
「同じメモリを見ているのだから、書いたら読めるだろう」
読めることはあります。
でも、それは 正しいタイミングで、正しい単位で、正しい順序で 読めることを意味しません。
Windows でも POSIX でも、共有メモリへのアクセスは 別の同期手段と組み合わせる前提 です。
Windows の説明でも、共有 view へのアクセスは mutex / semaphore / event などで協調するよう書かれています。2
POSIX の説明でも、shared memory へのアクセスは同期が必要です。9
5.2 volatile で何とかしようとする
volatile は、共有メモリ設計を救ってくれる魔法ではありません。
少なくとも atomicity と mutual exclusion は別問題です。45
たとえば volatile bool ready; を置いて busy loop する設計は、
- CPU を無駄に使う
- payload と ready の順序保証が曖昧になる
- portable ではない
- 途中状態を拾いやすい
と、だいたい良いことがありません。
さらに Windows の WaitOnAddress は 同じプロセス内の thread 向け です。
cross-process の待機機構としては考えないほうが安全です。10
5.3 途中状態を読ませる
共有メモリで事故るときの見た目は、かなり普通です。
- ヘッダだけ新しい
- ペイロードだけ古い
- 長さだけ更新済み
- 2 つのフィールドの組が壊れている
単一の scalar を atomic に更新するだけなら話は比較的単純ですが、複数フィールドからなるレコード を公開するなら、commit の手順が必要です。
典型的には次のどれかです。
- mutex で丸ごと守る
- ダブルバッファ にして最後に「今の有効バッファ番号」を切り替える
- リングバッファ にして slot ごとに state / sequence を持つ
- 1 writer / 多 reader なら sequence counter で snapshot を取る
「最後に ready flag を立てる」だけでも、その flag をどういうメモリ順序で書くか / 読むか を決めないと、設計としてはまだ甘いです。
共有メモリでは、公開タイミングそのものがプロトコル です。
5.4 ポインタや複雑オブジェクトをそのまま置く
これはかなり頻出です。
- 生ポインタ
HANDLE- file descriptor
std::stringstd::vectorstd::unordered_mapstd::mutexCRITICAL_SECTION
このへんを shared memory にそのまま置いて、別プロセスから使おうとするやつです。だいたい小さな地獄が始まります。
理由は単純で、仮想アドレスや process-local な資源は、その process の文脈にしか意味がない からです。
Windows の view も、同じ mapping を別 process で map しても、仮想アドレスは一致するとは限りません。711
なので、参照が必要なら ベースアドレスからの offset で持つのが基本です。
typedef struct ShmRef {
uint64_t offset; // セグメント先頭からの相対位置
uint32_t length;
uint32_t kind;
} ShmRef;
これなら、各 process が base + offset で自分のアドレスに直せます。
5.5 ABI が壊れる
shared memory は、ソースコードではなく バイナリの約束 です。
つまり、次の違いが全部効きます。
int/longのサイズboolの表現enumの underlying typewchar_tのサイズ- 32bit / 64bit の差
#pragma pack- compiler / language の違い
- alignment / padding
- little-endian / big-endian
同一ホスト内なら endianness は揃っていることが多いですが、ARM64 対応や mixed toolchain が入るだけでも、かなり普通にずれます。
なので、shared memory に置く構造は次を強く勧めます。
uint32_t/uint64_tなどの 固定幅整数- 明示的な padding / reserved
- header に
version,header_size,record_size,total_size - 必要なら
static_assert(sizeof(...)) - 非 trivial object を置かない
5.6 初期化レース
shared memory は「作った側が初期化したはず」という思い込みで壊れやすいです。
Windows では、CreateFileMapping が既存名に当たると 既存オブジェクトを返し、GetLastError() で ERROR_ALREADY_EXISTS が分かります。
pagefile-backed な mapping の初期ページは 0 で始まります。8
POSIX では、新しい shared memory object は 最初は長さ 0 で、ftruncate でサイズを付けます。新しく確保されたバイトは 0 初期化です。O_CREAT | O_EXCL による create は原子的です。3
この差を知らないまま、
- open したら即使う
- 初期化完了フラグがない
- 参加者が同時に初期化する
- version mismatch を見ない
とやると、起動順次第で壊れます。
最低限、先頭ヘッダに次の state を置いたほうがよいです。
INITIALIZINGREADYBROKEN
そして creator だけが初期化 し、joiner は READY を待つ。
この作法だけで、かなり世界が静かになります。
5.7 クラッシュ復旧を考えない
writer が共有データ更新中に落ちたらどうするか。
ここを未定義のまま本番へ出すと、障害時の顔つきが急に深刻になります。
Windows の mutex は、所有 thread が release せずに終了すると abandoned になり、wait 側は WAIT_ABANDONED を受け取れます。これは 共有資源が不定状態かもしれない という意味です。12
POSIX の robust mutex でも、owner が死んだとき EOWNERDEAD が返り、修復後に pthread_mutex_consistent() を呼ぶ流れがあります。1314
大事なのは、ここで「とりあえず続行」しないことです。
復旧には少なくとも次のどれかが要ります。
- generation 番号
- 最終 commit 済み sequence
- heartbeat
- dirty / clean flag
- journal 的な 2 段 commit
- 破損時の全再初期化手順
5.8 false sharing とキャッシュライン競合
shared memory は速い、と言われがちです。
でも hot なカウンタが同じ cache line に詰まっていると、CPU 間で line が行ったり来たりして、景気よく遅くなります。
典型例は、
- producer が
write_indexを更新 - consumer が
read_indexを更新 - 両方が同じ cache line に乗っている
というやつです。
この場合は、
- hot field を別 cache line に分ける
- 更新頻度の高い field と低い field を分ける
- 1 writer 1 cache line を意識する
だけでかなり変わります。
64 bytes に揃える話がよく出ますが、64 bytes は多くの CPU でありがちな値であって絶対法則ではない、くらいの気持ちで見てください。
5.9 名前・権限・セキュリティを軽く見る
named shared memory は便利ですが、名前と権限を雑にすると事故ります。
Windows では、
Global\とLocal\の namespace がある- session 0 以外から
Global\の file mapping を 新規作成 するにはSeCreateGlobalPrivilegeが要る - object name は event / semaphore / mutex / waitable timer / job と namespace を共有 する
つまり、
"Global\\MyApp"にしたら service と desktop app で共有できる気がする- でも権限で失敗する
- しかも同名の mutex を先に作っていて
ERROR_INVALID_HANDLEになる
みたいな、たいへん Windows らしい泥が出ます。
POSIX 側でも、shm_open の mode や umask を軽く見ると、不要に広く見えたり、逆に開けなかったりします。3
shared memory は ただメモリだから安全 ではありません。
読める権限がある process からは、かなり素直に見えます。
機密情報を置くなら、通常のメモリと同じく paging / swap / dump / 権限の文脈で考える必要があります。
5.10 サイズ変更とアップグレードを雑にやる
共有メモリを「あとからちょっと広げたい」は、わりと危ない要求です。
実務では、サイズはその世代では不変 にしたほうが安全です。
拡張が必要なら、
- 新しい version / name / generation の segment を作る
- 参加者を切り替える
- 旧 segment を閉じる
のほうが事故率は下がります。
5.11 通知まで全部 shared memory に押し込む
よくあるのが、
- 共有メモリに
ready = 1 - 相手は
while (!ready) Sleep(1);
です。
これ、最初は動きます。
でも後で、
- CPU を無駄に使う
Sleep(1)でレイテンシが揺れる- 取りこぼしに気づきにくい
- タイムアウトや終了通知がきれいに書きづらい
という形で返ってきます。
共有メモリは データ面 に寄せ、通知は 待てる primitive へ逃がしたほうがよいです。
- Windows: event / semaphore / mutex / named pipe など217
- POSIX: semaphore / process-shared mutex + condvar など1819
5.12 「これで他マシンとも共有できる」と思う
file-backed mapping を使ってネットワーク越しの共有ファイルを map すれば、他マシンとも shared memory 的にいけるのでは、と思いたくなる瞬間があります。
ここは危ないです。
Windows の CreateFileMapping の説明でも、remote file に対しては coherence が保証されない とされています。
同じページを 2 台が writable に map した場合、それぞれ自分の書き込みしか見えず、ディスク更新時に merge もされません。8
共有メモリは、基本的に 同一ホスト内 の仕組みです。
マシンをまたぐなら、素直に socket / RPC / message broker を選んだほうが正気を保ちやすいです。
6. ベストプラクティス
6.1 control plane と data plane を分ける
shared memory には バルクデータだけ を置き、通知と状態遷移は別チャンネルへ逃がします。
- shared memory: frame, sample, batch, snapshot
- event / semaphore / pipe / socket: ready, consumed, stop, error, reconnect
この分離は、性能より先に 設計の見通し を良くします。
6.2 先頭に固定ヘッダを置く
最低限、先頭にこういうヘッダを置くことを強く勧めます。
typedef struct SharedHeader {
uint32_t magic;
uint16_t abi_version;
uint16_t header_size;
uint32_t state; // 0=initializing, 1=ready, 2=broken
uint32_t flags;
uint64_t total_size;
uint64_t generation;
uint64_t heartbeat_ns;
uint64_t payload_offset;
uint64_t payload_size;
uint64_t write_seq;
uint64_t read_seq;
uint8_t reserved[64];
} SharedHeader;
ポイントは、
magicで別物や未初期化を弾くabi_versionとheader_sizeで layout 差異を弾くstateで初期化途中を弾くgenerationで再作成を検知するheartbeatで死活を見るreservedで将来拡張の逃げ道を作る
です。
shared memory で辛いのは、「何が起きているか見えにくい」ことです。
だからこそ、観測用の metadata を最初から持たせます。
6.3 オフセット参照にする
参照は pointer ではなく offset で持ちます。
base + offsetで解決するoffset + lengthの範囲チェックを入れる- invalid value 用の sentinel を決める
これだけで、address mismatch 系の事故がかなり減ります。
6.4 並行モデルを絞る
shared memory は、writer が増えると急に難しくなります。
なので、最初はこのどちらかが強いです。
- SPSC ring buffer
- 1 writer / 多 reader の snapshot
多 writer が必要なら、
- enqueue だけは lock-free / atomic
- 実データ更新は consumer 1 つへ集約
のように、整合性の責任点を減らす ほうがだいたいうまくいきます。
6.5 commit protocol を明示する
「どの瞬間から読んでよいか」を文章で説明できない設計は危ないです。
たとえばダブルバッファなら、
- 非公開側バッファへ書く
- チェックサムや長さを確定する
- release 付きで active buffer index を切り替える
- reader は acquire 付きで active index を読む
- 読み終えたら index が変わっていないか確認する
のように、公開の儀式 を決めます。
6.6 サイズは世代ごとに固定する
resize in place より、
name = MyShm.v3abi_version = 3generation = 42
のように世代を切ったほうが保守しやすいです。
共有メモリは API のように「呼び出し時に型チェック」してくれません。
だから 一度決めた ABI をこわさない ことが重要です。
6.7 観測可能性を入れる
最低限あると助かるのは次です。
- 最終更新時刻
- 最終成功 sequence
- drop 数 / overwrite 数
- version mismatch 数
- attach / detach 数
- last error code
- heartbeat
shared memory が壊れるときは、だいたいログが薄いです。
自前で counters を置くと、障害対応がかなり楽になります。
6.8 異常系テストを先に作る
正常系だけでは足りません。少なくとも次は見たほうがいいです。
- writer 更新中に強制終了
- reader 遅延で ring があふれる
- version mismatch で接続
- 32bit / 64bit 混在
- session をまたいだ open
- 権限不足
- 先行プロセスが古い世代を持ったまま再起動
- huge data 連続転送時の cache miss / NUMA 影響
shared memory は正常系より 壊し方テスト のほうが価値が大きいです。
7. Windows と POSIX で見るポイント
| 観点 | Windows | POSIX |
|---|---|---|
| 作成 / open | CreateFileMapping / OpenFileMapping / MapViewOfFile6 |
shm_open / ftruncate / mmap3 |
| ディスク非連携の共有 | INVALID_HANDLE_VALUE を指定した pagefile-backed mapping68 |
POSIX shared memory object + mmap3 |
| 初期値 | pagefile-backed pages は 0 初期化8 | 新規 object は長さ 0。新規確保バイトは 0 初期化3 |
| 同期 | mutex / semaphore / event / interlocked など25 | process-shared mutex / condvar / semaphore2018 |
| cross-process で使ってはいけないもの | CRITICAL_SECTION, WaitOnAddress2110 |
PTHREAD_PROCESS_PRIVATE のままの mutex / condvar2019 |
| owner death | WAIT_ABANDONED12 |
robust mutex + EOWNERDEAD / pthread_mutex_consistent()1314 |
| name の削除 | 最終 handle / view 解放で消える28 | shm_unlink で名前削除。参照が残っていれば実体は最後まで残る2223 |
| namespace / 権限 | Global\ / Local\、ACL、SeCreateGlobalPrivilege1524 |
mode, umask, 名前空間、O_CREAT|O_EXCL3 |
C# の MemoryMappedFile も、本質的には Windows の file mapping のラッパです。
だから、
- 同じ名前で open する
- 別途 mutex / event を使う
- ビューに対して明示レイアウトで読む
- オブジェクト参照をそのまま置かない
という基本は変わりません。1
8. まず見るチェックリスト
- 本当に共有メモリが要るか。同一ホストで大きなデータ か
- control plane と data plane を分けたか
- 並行モデルは SPSC / 1 writer 多 reader まで落とせないか
- 先頭ヘッダに magic / version / size / state / generation / heartbeat があるか
- pointer /
HANDLE/ fd / STL object /std::mutexを置いていないか - reader が途中状態を見ない commit protocol があるか
- 初期化者が 1 人に定まっているか
- 異常終了時の 復旧手順 があるか
- 名前と権限を明示しているか
Global\が本当に必要か- resize in place を前提にしていないか
- writer kill / reader stall / version mismatch / 権限不足を試したか
9. まとめ
共有メモリは、うまく使えばかなり強いです。
特に、
- 画像
- 音声
- センサ列
- 大きなバッチ
- 高頻度 snapshot
のような 同一マシン内の大きなデータ では、本当に効きます。
ただし、共有メモリの本体は「速さ」より 責任の移動 です。
コピーやカーネル越しのメッセージングを減らす代わりに、
- 同期
- 可視性
- 初期化
- ABI
- 復旧
- 権限
- 観測可能性
をこちらで引き受けることになります。
なので、最初の 1 本目はこうするのが安全です。
- SPSC ring buffer かダブルバッファ
- 先頭固定ヘッダ
- offset 参照
- 別チャネルで通知
- version / generation / heartbeat あり
- 異常系テストあり
この形から始めると、shared memory はかなり素直な道具になります。
逆に、いきなり「何でも置ける速い共通メモリ」として扱うと、だんだんアプリではなく考古学になります。
10. 参考資料
- Windows: file mapping と named shared memory の基本682
- Windows: namespace / security / synchronization1524512
- POSIX:
shm_open,shm_unlink,mmap, process-shared / robust synchronization322162013 - .NET:
MemoryMappedFileの概要1
-
Microsoft Learn, “メモリ マップト ファイル” https://learn.microsoft.com/ja-jp/dotnet/standard/io/memory-mapped-files / Microsoft Learn, “MemoryMappedFile クラス” https://learn.microsoft.com/ja-jp/dotnet/api/system.io.memorymappedfiles.memorymappedfile?view=net-10.0 ↩ ↩2 ↩3
-
man7.org, “shm_open(3)” https://man7.org/linux/man-pages/man3/shm_open.3.html ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11
-
Microsoft Learn, “/volatile (volatile Keyword Interpretation)” https://learn.microsoft.com/en-us/cpp/build/reference/volatile-volatile-keyword-interpretation?view=msvc-170 / Microsoft Learn, “volatile (C++)” https://learn.microsoft.com/en-us/cpp/cpp/volatile-cpp?view=msvc-170 ↩ ↩2
-
Microsoft Learn, “Interlocked Variable Access” https://learn.microsoft.com/en-us/windows/win32/sync/interlocked-variable-access / Microsoft Learn, “MemoryBarrier function” https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-memorybarrier ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, “Creating Named Shared Memory” https://learn.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory / Microsoft Learn, “名前付き共有メモリの作成” https://learn.microsoft.com/ja-jp/windows/win32/memory/creating-named-shared-memory ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, “Scope of Allocated Memory” https://learn.microsoft.com/en-us/windows/win32/memory/scope-of-allocated-memory ↩ ↩2
-
Microsoft Learn, “CreateFileMappingA function” https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9
-
man7.org, “POSIX Shared Memory” training slides https://man7.org/training/download/ipc_pshm_slides-mkerrisk-man7.org.pdf ↩
-
Microsoft Learn, “WaitOnAddress function” https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitonaddress ↩ ↩2
-
Microsoft Learn, “MapViewOfFileEx function” https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffileex / Microsoft Learn, “MapViewOfFile function” https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile ↩
-
Microsoft Learn, “Mutex Objects” https://learn.microsoft.com/en-us/windows/win32/sync/mutex-objects ↩ ↩2 ↩3
-
man7.org, “pthread_mutex_lock(3p)” https://man7.org/linux/man-pages/man3/pthread_mutex_lock.3p.html / man7.org, “pthread_mutexattr_setrobust(3)” https://man7.org/linux/man-pages/man3/pthread_mutexattr_setrobust.3.html ↩ ↩2 ↩3
-
man7.org, “pthread_mutex_consistent(3)” https://man7.org/linux/man-pages/man3/pthread_mutex_consistent.3.html / man7.org, “pthread_mutex_consistent(3p)” https://man7.org/linux/man-pages/man3/pthread_mutex_consistent.3p.html ↩ ↩2
-
Microsoft Learn, “Kernel object namespaces” https://learn.microsoft.com/en-us/windows/win32/termserv/kernel-object-namespaces ↩ ↩2 ↩3
-
man7.org, “mmap(2)” https://man7.org/linux/man-pages/man2/mmap.2.html ↩ ↩2
-
Microsoft Learn, “Using Mutex Objects” https://learn.microsoft.com/en-us/windows/win32/sync/using-mutex-objects ↩
-
man7.org, “sem_init(3)” https://man7.org/linux/man-pages/man3/sem_init.3.html / man7.org, “sem_init(3p)” https://man7.org/linux/man-pages/man3/sem_init.3p.html ↩ ↩2
-
Microsoft Learn, “Critical Section Objects” https://learn.microsoft.com/en-us/windows/win32/sync/critical-section-objects ↩
-
man7.org, “shm_unlink(3p)” https://man7.org/linux/man-pages/man3/shm_unlink.3p.html ↩ ↩2
-
man7.org, “shm_open(3)” (shm_unlink semantics) https://man7.org/linux/man-pages/man3/shm_open.3.html ↩
-
Microsoft Learn, “ファイル マッピングのセキュリティとアクセス権” https://learn.microsoft.com/ja-jp/windows/win32/memory/file-mapping-security-and-access-rights / Microsoft Learn, “File Mapping Security and Access Rights” https://learn.microsoft.com/en-us/windows/win32/memory/file-mapping-security-and-access-rights ↩ ↩2
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
このテーマがつながるサービス
この記事は次のサービスページにつながります。近い入口からご覧ください。
Windowsアプリ開発
共有メモリ、file mapping、MemoryMappedFile を使った大容量データ連携やプロセス分離設計は、Windows アプリ開発と直結するテーマです。
技術相談・設計レビュー
同期方式、ABI 設計、復旧戦略、control plane と data plane の分離など、事故率を下げる設計整理は技術相談・設計レビューと相性がよいです。