0

私は共有メモリが初めてで、実際の例を探していました.MSDNでしか見つけることができませんでした

最初のプロセスで、共有メモリを次のように宣言しました。

hFileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, dwDataSize, strSharedMemoryName.c_str());
pBuffer = ::MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, dwDataSize);
::CopyMemory(pBuffer, pData, dwDataSize);

そして2番目のプロセスで:

HANDLE hFileMap = ::OpenFileMapping(FILE_MAP_READ, FALSE, strContentsSizeFileMap.c_str());
LPVOID pData = ::MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);

mapView の作業が完了したら、' UnmapViewOfFile()' を使用して解放する必要があることはわかっています。私の質問は、正確にはどこですか?

  1. 親プロセス?
  2. 子プロセス
  3. 両方?

両方にある場合、OS は完全に解放される前にアドレスの参照カウントを保持しますか?

MSDN から:

また、対応する物理ページの共有数を減らします

これにより、実際に何をすべきかについて少し混乱しました。

4

2 に答える 2

3

https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537%28v=vs.85%29.aspx

CreateFileMapping 関数
指定されたファイルの名前付きまたは名前なしのファイル マッピング オブジェクトを作成または開きます。
...
ファイル マッピング オブジェクトを作成しても、実際にはビューがプロセス アドレス空間にマップされません。MapViewOfFile および MapViewOfFileEx 関数は、ファイルのビューをプロセス アドレス空間にマップします。
...
ファイル マッピング オブジェクトのマップされたビューは、オブジェクトへの内部参照を維持し、ファイル マッピング オブジェクトは、それへのすべての参照が解放されるまで閉じません。したがって、ファイル マッピング オブジェクトを完全に閉じるには、アプリケーションは、UnmapViewOfFileを呼び出してファイル マッピング オブジェクトのすべてのマップされたビューのマップを解除し、 CloseHandleを呼び出してファイル マッピング オブジェクト ハンドルを閉じる必要があります。. これらの関数は、任意の順序で呼び出すことができます。

したがって、プロセス #1 はオペレーティング システムでマップ オブジェクトを作成します。次に、プロセス #1 はその一部を自身のプロセス メモリにマップします。
プロセス #2 は、同じオペレーティング システム マッピング オブジェクトへのハンドルを取得し、その同じ部分または異なる部分を独自のメモリにマップします。
いずれかのプロセスが終了すると、UnmapViewOfFileそれ自体のプロセス メモリからマッピングを削除する を呼び出しCloseHandle、オペレーティング システム マップへのハンドルを呼び出します。Windows ハンドルはすべて実質的に参照カウントされるため、ハンドルを持つすべてのプロセスが を呼び出すCloseHandleと、オペレーティング システムはマップ オブジェクトを自動的に破棄します。

これは、プロセス #1 がマッピングを作成し、マッピングを使用し、それを完全に閉じ、プロセス #2 がそのマッピングを開こうとした場合、プロセス #2 は失敗することに注意してください。これを回避するには、ファイルシステムにファイルを作成してメモリをバックアップします。これにより、ファイルを削除するまでメモリがプロセス間で保持されます。

于 2015-03-25T16:59:25.210 に答える
1

MapViewOfFile を呼び出すすべてのプロセスは、共有メモリの使用が終了したときに UnmapViewOfFile を呼び出す必要があります。それは通常、プログラムがシャットダウンするときです。

于 2015-03-25T16:16:20.937 に答える