프로세스간에 데이터를 공유할 때..
많이 사용되는 방법중에 하나가 공유 메모리(Memory Mapped File)를 사용하는 것이다.
일단 서버에서는 읽고/쓰기 모드로 열어서 내부에서 사용하고..
다른 한쪽 혹은 여러클라이언트 에서는 읽기 전용 모드로 열어서 사용하는 가장 간편한 방법을 사용해보자.
(사용하는 방식은 메모리를 액세스하는것과 동일하다..) 



위 그림처럼, 하나의 메모리 공간을 양쪽에서 액세스 할 수 있도록 제공해주는 점이 탁월한 장점이고,
또한 멀티 쓰레드? 멀티 코어? 와 상관없이...
서버는 읽기/쓰기 규칙을 지키고, 클라이언트는 읽기만 한다면 절대 공유 액세스 위반을 걱정할 필요가 없다.

우선 사용되는 API를 살펴보자. 아래에 해당하는 5개의 API만 사용해도 되며,
CreateFileMapping 함수의 첫번째(hFile) 인자와, 여섯번째(lpName) 인자만 주의하면 특별하게
인자에 신경쓰지 않아도 된다.

HANDLE WINAPI CreateFileMapping(
 __in          HANDLE hFile,
 __in          LPSECURITY_ATTRIBUTES lpAttributes,
 __in          DWORD flProtect,
 __in          DWORD dwMaximumSizeHigh,
 __in          DWORD dwMaximumSizeLow,
 __in          LPCTSTR lpName
);

※ HANDLE hFile
사용자가 이미 만들어 놓은 파일 핸들이나, INVALID_HANDLE_VALUE 를 전달할 수 있으며, INVALID_HANDLE_VALUE 이
전달되었을 경우는 시스템의 페이지 파일을 할당
해서 사용한다.
그러므로, 특별하게 큰 파일을 사용하는 경우가 아니라면 INVALID_HANDLE_VALUE 만으로도 충분하다.

※ LPCTSTR lpName
해당 공유 메모리를 확인하기 위한 고유한 이름을 나타낸다. 일반적인 클라이언트 OS 에서는 별 문제가 없겠지만
서버 OS에 Terminal Service 가 구동중이라면 Prefix 에 따라 그 특성이 달라진다.
모든 세션에서 접근할 수 있으려면 Global\이름 과 같이 Global\ 라는 Prefix를 붙혀주어야 한다.

HANDLE WINAPI OpenFileMapping(
 __in          DWORD dwDesiredAccess,
 __in          BOOL bInheritHandle,
 __in          LPCTSTR lpName
);

LPVOID WINAPI MapViewOfFile(
 __in          HANDLE hFileMappingObject,
 __in          DWORD dwDesiredAccess,
 __in          DWORD dwFileOffsetHigh,
 __in          DWORD dwFileOffsetLow,
 __in          SIZE_T dwNumberOfBytesToMap
);

BOOL WINAPI UnmapViewOfFile(
 __in          LPCVOID lpBaseAddress
);

BOOL WINAPI CloseHandle(
 __in          HANDLE hObject
);




※ 참고로, 서버프로그램이 종료되었을 경우, 클라이언트에서 메모리 맵드 파일의 현황만 가지고는 알수 없다는 단점이 있다.
즉, 서버가 죽어도 클라이언트가 살아서 데이터를 읽는데는 전혀 문제가 없기 때문에.. 이러한 부분은 별도로 확인해 주어야한다.

+ Recent posts