2010-11-29 11 views
0

私はメモリマッピングを使用してファイルを開く予定です。CreateFileMappingはプログラム間で同期しますか?

ファイルはすでに別のプロセスによって同じ方法で開いています。つまり、独自のメモリマップビューが開いていて、時折ファイルが編集されます。

同じファイルを自分自身で編集し、他のプロセスの変更を上書きすることなく、他のプロセスとできるだけ効率的にアクセスしたいと思います。私が最初にすべてのファイルを直接開くことができ

IntPtr f_ptr = CreateFile(
path, 
GENERIC_READ | GENERIC_WRITE, 
FILE_SHARE_READ | FILE_SHARE_WRITE, 
IntPtr.Zero, 
OPEN_ALWAYS, 
FILE_FLAG_RANDOM_ACCESS, 
IntPtr.Zero); 

は、直接ファイルのバイナリを編集する、しかし、他のプロセスのメモリマッピングオブジェクトが過書き込み、私の変更をしやすいという点では効果がありません。

私自身のファイルマッピングと私自身のビューを開いた場合、以下のように、他のプロセスは自分の編集内容を上書きしないように自分の編集内容で自動的に更新されるようです。

ここではどのような同期が行われていますか?

他のプロセスのファイルマッピングにマップされた独自のビューを開いているわけではありません。私は同じファイルにまったく新しいFileMappingを作成しました。

ファイルシステムまたはFileMappingシステムは、これを何らかの形で理解しているようです。どうして?

// file map pointer 
IntPtr m_ptr = CreateFileMapping(f_ptr, IntPtr.Zero, PAGE_READWRITE, 0, 0, "MyMapping"); 

// map view pointer 
IntPtr view_ptr = MapViewOfFileEx(m_ptr, FILE_MAP_WRITE, 0, 0, 0, IntPtr.Zero); 

// EDIT FILE CONTENTS 

FlushViewOfFile(view_ptr, 0); 
UnmapViewOfFile(view_ptr); 

CloseHandle(m_ptr); 
+0

正確なアナログは、同じ配列にアクセスする2つのスレッドです。同じ要素にアクセスするには、ロックが必要です。名前付きのmutexです。 –

答えて

0

ファイルの書き込み可能なビューを持つ人は、いつでも書き込みできます。両方のエディタが確実に変更を書き出すことができるようにするには、変更が重複する場合に独自の競合解決を実行する必要があります。

これは解決するのが非常に単純な問題のようには思えません。複数の編集を統制された方法でマージするために、単純なドキュメントバージョン管理システムが必要なことがあります。

0

1つのアイデアは、名前付きのミューテックス(名前パラメータがNULLではないCreateMutex()を呼び出して作成できる)を取得している間に、書き込み(およびFlushViewOfFile()呼び出し)ができることです。

例えば(エラーが省略取り扱い):

HANDLE hMutex, hMap; 
PVOID pView; 

// In reality, it might be good to dynamically generate the name based on 
// the file being mapped (eg. its volume and file ID, something like this..) 
hMutex = CreateMutex(NULL, FALSE, TEXT("Local\\LockForThisFile")); 

hMap = CreateFileMapping(/* ... */); 
pView = MapViewOfFile(/* ... */); 

// Some time later, when you need to do the writes... 
// 
WaitForSingleObject(hMutex, INFINITE); 
PerformWrites(pView); 
FlushViewOfFile(pView, 0); 
ReleaseMutex(hMutex); 

あなたがこれにアクセスする方法に応じて、読みながらも、ロックを獲得する必要があるかもしれません。これはもちろん同時性を制限します。

ところで、解説:あなたがFlushViewOfFileコールで「ビューの開始から終了まで」よりも具体的なら

  • これもパフォーマンスが向上することがあります。たとえば、オフセットinバイトを書き込む場合、FlushViewOfFile(pView + i, n);と言うことができます。 OSがどのページが汚れているかを確認し、最小限の書き込みしか行わない可能性がありますが(MSDNではこれが示唆されているようです)、おそらくより小さな範囲でうまくいくでしょう。それは私のところでの推測です。

  • ファイルのマッピング時に、I/Oが失敗した場合にポインタの参照を解除するEXCEPTION_IN_PAGE_ERROR例外が発生することがあります。あなたはSEHでそれらを捕まえることができます(this MSDN pageのように)。

関連する問題