2010-11-29 13 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

정확한 아날로그는 동일한 배열에 액세스하는 두 개의 스레드입니다. 동일한 요소에 액세스하는 경우 잠금이 필요합니다. 전형적으로 명명 된 뮤텍스. –

답변

0

파일의 쓰기 가능 권한이있는 사람은 언제든지 파일에 쓸 수 있습니다. 두 편집자가 변경 사항을 안정 적으로 작성할 수 있도록하려면 변경 사항이 중복되는 곳에서 자체적 인 충돌 해결을 수행해야합니다.

이것은 해결하기가 매우 간단한 문제는 아닙니다. 제어 된 방식으로 여러 편집 내용을 병합하려면 간단한 문서 버전 시스템이 필요합니다.

0

하나의 아이디어는 이름이 지정된 뮤텍스 (이름 매개 변수가 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에서와 같이)를 가진 사람들을 잡을 수 있습니다.