메뉴 닫기

[WinAPI] 프로세스 간 통신 방법, CreateFileMapping과 MapViewOfFile 활용법

[WinAPI] 프로세스 간 통신 방법, CreateFileMapping과 MapViewOfFile 활용법

🧩 서로 다른 프로세스 간 데이터를 안전하게 공유하는 가장 확실한 방법!

운영체제의 핵심인 프로세스 간 통신(IPC, Inter-Process Communication)은 개발자라면 반드시 이해해야 할 개념 중 하나입니다.
특히 WinAPI 기반 시스템 프로그래밍에서는 메모리 맵 파일을 활용한 통신 방식이 널리 사용되며, CreateFileMappingMapViewOfFile은 그 핵심 함수로 꼽힙니다.
이 글에서는 이들 API를 활용해 실제로 프로세스 간 데이터를 어떻게 공유할 수 있는지, 어떤 상황에서 사용하면 효과적인지를 쉽고 명확하게 설명해드릴게요.

단순히 코드만 나열하는 기술 포스트가 아닙니다.
왜 이 방식이 필요한지, 어떤 원리로 동작하는지, 그리고 실무에서 어떻게 응용할 수 있는지까지 짚어보며 초보자도 완전히 이해할 수 있도록 도와드립니다.
IPC 방식 중에서도 안정성과 성능을 모두 잡을 수 있는 메모리 맵 방식의 통신 구조에 대해 관심 있다면 지금 바로 아래 내용을 확인해보세요!



🧠 프로세스 간 통신이란?

운영체제에서 실행 중인 프로그램은 각각 독립적인 프로세스로 동작하며, 기본적으로는 서로의 메모리에 접근할 수 없습니다.
이는 보안을 위한 설계이지만, 반대로 프로세스 간에 정보를 주고받아야 할 때는 통신 수단이 필요하다는 뜻이기도 하죠.

이럴 때 사용하는 기술이 바로 IPC(Inter-Process Communication)입니다.
IPC는 하나의 프로세스가 생성한 데이터를 다른 프로세스가 받아 처리하거나, 양방향으로 데이터를 주고받을 수 있도록 돕는 메커니즘이죠.

IPC 방식은 매우 다양합니다.
이벤트, 파이프, 메시지 큐, 소켓, 공유 메모리 등 여러 방식이 존재하며, 각각 장단점이 뚜렷합니다.
그 중에서도 공유 메모리(Shared Memory)는 속도가 빠르고 구조가 간단해 고성능이 요구되는 애플리케이션에서 널리 사용됩니다.

  • 📌파이프(Named Pipe): 커널이 관리하는 통신 채널로, 구조가 명확하고 보안 적용이 쉬움
  • 📌소켓(Socket): 네트워크 기반 IPC로 로컬은 물론 원격 프로세스 간 통신도 가능
  • 📌공유 메모리(Memory Mapped File): 속도가 가장 빠르지만 메모리 관리 주의 필요

이 글에서 다루는 방식은 마지막 항목인 메모리 맵 방식의 IPC입니다.
WinAPI에서는 CreateFileMappingMapViewOfFile을 통해 이러한 공유 메모리를 생성하고 접근할 수 있습니다.
다음 섹션부터 이 방식의 장점과 실제 사용법을 하나씩 알아보겠습니다.

🔐 메모리 맵 방식의 장점

WinAPI에서 제공하는 메모리 맵 방식은 고속의 데이터 전송낮은 시스템 리소스 소비라는 측면에서 매우 유리한 통신 방식입니다.
특히 대량의 데이터를 자주 주고받는 애플리케이션에서는 그 효율성이 더욱 돋보이죠.

이 방식은 실제로 하나의 메모리 공간을 두 개 이상의 프로세스가 동시에 참조하는 구조를 가지고 있습니다.
운영체제는 이 메모리를 커널 레벨에서 관리하며, 필요한 시점에만 해당 메모리를 실제 물리 메모리로 매핑합니다.
이로 인해 디스크 I/O나 별도의 전송 로직 없이 즉시 접근이 가능해지는 장점이 있죠.

💎 핵심 포인트:
공유 메모리는 파일 기반 매핑을 통해 생성되므로 다른 프로세스와의 데이터 동기화가 간편하고 빠릅니다.

또한, 다른 IPC 방식과 비교했을 때 다음과 같은 장점들이 두드러집니다.

  • 🚀속도: 디스크를 거치지 않아 매우 빠른 데이터 접근 가능
  • 🔄동기화: 별도의 전송 로직 없이 데이터를 실시간 공유
  • 📉자원 효율: 프로세스 간 최소한의 리소스만으로 통신 가능

단, 모든 상황에 적합한 것은 아니며 메모리 접근 동기화 문제보안 설정에 대한 고려도 필요합니다.
이러한 점을 감안하면, 공유 메모리는 빠른 속도와 낮은 비용이 중요한 상황에서 탁월한 선택이 될 수 있습니다.



🛠️ CreateFileMapping 함수 이해하기

WinAPI에서 공유 메모리를 만들기 위해 사용하는 핵심 함수가 바로 CreateFileMapping입니다.
이 함수는 실제 파일이든, 시스템 페이징 파일(Page File)이든 특정 영역을 메모리에 매핑하여 공유 가능한 핸들을 생성해 줍니다.

핵심적으로 이해해야 할 점은 이 함수 자체가 메모리 공간을 만드는 것이 아니라, 매핑 객체를 생성한다는 것입니다.
그 후 다른 프로세스에서는 동일한 이름을 통해 이 객체를 열고 사용할 수 있게 되죠.

💎 핵심 포인트:
CreateFileMapping을 사용할 때는 이름(Name)을 지정하는 것이 중요합니다. 같은 이름을 사용하면 다른 프로세스도 동일한 메모리 영역을 공유할 수 있습니다.

CODE BLOCK
HANDLE hMapFile = CreateFileMapping(
    INVALID_HANDLE_VALUE,    // 시스템 페이지 파일 사용
    NULL,                    // 기본 보안 속성
    PAGE_READWRITE,          // 읽기/쓰기 접근
    0,                       // 최대 객체 크기 (상위 32비트)
    1024,                    // 최대 객체 크기 (하위 32비트)
    TEXT("Global\\MySharedMemory")  // 공유 메모리 이름
);

위 예시에서 INVALID_HANDLE_VALUE는 파일 대신 시스템의 페이징 파일을 사용하겠다는 의미입니다.
이 방식은 파일 없이도 프로세스 간 메모리 공유를 가능하게 해주죠.

그리고 TEXT(“Global\\MySharedMemory”)처럼 전역 네임스페이스를 사용하면 세션을 넘어서도 다른 프로세스와의 공유가 가능합니다.
단, 관리자 권한이 필요한 경우도 있으니 보안 컨텍스트를 잘 확인해야 합니다.

🔍 MapViewOfFile로 메모리 접근하기

이제 CreateFileMapping으로 생성한 공유 메모리를 실제로 접근하려면 MapViewOfFile 함수를 사용해야 합니다.
이 함수는 지정된 매핑 객체의 내용을 프로세스 주소 공간에 매핑하여, 실제 포인터를 통해 데이터를 읽고 쓸 수 있게 만들어 줍니다.

사용 방식은 비교적 간단하지만, 접근 권한 설정과 오프셋, 크기 등을 정확히 지정해야 하며, 매핑이 끝난 후에는 반드시 UnmapViewOfFile로 메모리 해제를 해줘야 합니다.

💎 핵심 포인트:
MapViewOfFile은 공유 메모리의 주소 공간에 대한 직접 접근을 허용하는 만큼, 정확한 포인터 연산과 예외 처리가 매우 중요합니다.

CODE BLOCK
LPCTSTR pBuf = (LPTSTR) MapViewOfFile(
    hMapFile,           // 매핑 객체 핸들
    FILE_MAP_ALL_ACCESS,// 읽기/쓰기 권한
    0,                  // 상위 파일 오프셋
    0,                  // 하위 파일 오프셋
    0                   // 매핑 크기 (전체 매핑)
);

위 예제처럼 매핑 객체를 전역으로 접근하고 싶다면, FILE_MAP_ALL_ACCESS 플래그를 지정해야 하며, 접근 권한이 충분하지 않다면 실패할 수 있습니다.
이후 pBuf를 통해 문자열을 복사하거나 구조체 데이터를 주고받는 것도 가능합니다.

  • 🔑접근 권한 플래그를 올바르게 설정해야 함
  • 📏파일 오프셋과 크기를 명확히 지정할 것
  • 🧼사용 후 반드시 UnmapViewOfFile로 메모리 해제

MapViewOfFile은 실질적으로 프로세스 간 통신의 핵심 포인터를 만들어내는 도구라 할 수 있습니다.
이제 이 기능을 이용해 두 개의 프로세스가 어떻게 데이터를 공유할 수 있는지, 실전 예제를 통해 살펴보겠습니다.



💡 실전 예제: 두 프로세스 간 문자열 공유

이제 지금까지 배운 내용을 바탕으로 두 개의 서로 다른 프로세스가 하나의 메모리를 공유하여 문자열 데이터를 주고받는 간단한 실전 예제를 소개합니다.
각 프로세스는 하나는 데이터를 쓰는 역할, 다른 하나는 읽는 역할을 수행하게 됩니다.

이를 통해 CreateFileMapping → MapViewOfFile → 공유 → Unmap → Close까지 전반적인 흐름을 실제로 확인해볼 수 있습니다.
먼저 데이터를 쓰는 Writer 프로세스의 예제를 살펴볼게요.

✍️ Writer 프로세스: 메모리에 문자열 쓰기

CODE BLOCK
HANDLE hMapFile = CreateFileMapping(
    INVALID_HANDLE_VALUE,
    NULL,
    PAGE_READWRITE,
    0,
    512,
    TEXT("Global\\MySharedMemory")
);

LPCTSTR pBuf = (LPTSTR) MapViewOfFile(
    hMapFile,
    FILE_MAP_ALL_ACCESS,
    0,
    0,
    0
);

CopyMemory((PVOID)pBuf, TEXT("안녕하세요! 공유 메모리입니다."), 100);

UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);

이 코드는 텍스트 문자열을 공유 메모리로 쓰는 역할을 합니다.
복사한 문자열은 이후 다른 프로세스에서 동일한 이름의 메모리 맵을 열어 접근할 수 있습니다.

📥 Reader 프로세스: 메모리에서 문자열 읽기

CODE BLOCK
HANDLE hMapFile = OpenFileMapping(
    FILE_MAP_ALL_ACCESS,
    FALSE,
    TEXT("Global\\MySharedMemory")
);

LPCTSTR pBuf = (LPTSTR) MapViewOfFile(
    hMapFile,
    FILE_MAP_ALL_ACCESS,
    0,
    0,
    0
);

_tprintf(TEXT("수신된 문자열: %s\n"), pBuf);

UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);

위 코드는 공유 메모리에 접근하여 저장된 문자열을 읽어 출력합니다.
이처럼 동일한 이름의 공유 메모리 핸들을 통해 두 프로세스 간 데이터 공유가 실현됩니다.

💬 실제 운영 환경에서는 문자열 외에도 구조체, 이미지 버퍼 등 다양한 데이터를 공유할 수 있습니다. 단, 동기화 처리와 접근 권한 관리에는 특히 주의가 필요합니다.

이제 여러분도 WinAPI를 통한 IPC 구현의 전체 흐름을 이해하셨을 겁니다.
다음은 자주 묻는 질문을 통해 추가적인 궁금증을 해결해드릴게요.

자주 묻는 질문 (FAQ)

CreateFileMapping 없이 메모리 공유가 가능한가요?
아니요. 공유 메모리 생성을 위해서는 반드시 CreateFileMapping이 필요합니다. 이 함수가 있어야 MapViewOfFile도 사용할 수 있습니다.
Global\\ 접두사는 꼭 써야 하나요?
Global\\ 또는 Local\\은 세션 간 메모리 공유 범위를 지정하는 접두사입니다. 여러 세션에서 공유하려면 Global\\을 반드시 사용해야 합니다.
CreateFileMapping은 어떤 크기까지 설정 가능한가요?
크기는 시스템의 가상 메모리 한도 내에서 가능합니다. 일반적으로 수백 MB에서 수 GB까지 할당할 수 있지만, OS 설정과 가용 메모리에 따라 달라집니다.
MapViewOfFile로 접근한 메모리는 어떻게 해제하나요?
사용이 끝난 후에는 반드시 UnmapViewOfFile 함수를 호출해야 합니다. 그렇지 않으면 메모리 누수가 발생할 수 있습니다.
같은 이름으로 두 번 CreateFileMapping 하면 어떻게 되나요?
이미 존재하는 이름일 경우 기존 핸들을 반환하게 됩니다. 새로 생성되지는 않으며 GetLastError로 기존 존재 여부를 확인할 수 있습니다.
보안 속성(Security Attributes)은 꼭 지정해야 하나요?
기본값(NULL)을 사용해도 대부분의 경우 문제가 없지만, 사용자 계정이나 세션 보안을 제어하려면 명시적으로 설정하는 것이 좋습니다.
문자열 외에 구조체도 공유 가능한가요?
가능합니다. 구조체 포인터로 캐스팅하여 데이터를 복사하거나 읽을 수 있으며, 메모리 정렬과 바이트 크기만 유의하면 됩니다.
다른 언어에서도 공유 메모리를 사용할 수 있나요?
네, C#, Python, C++ 등에서도 WinAPI를 호출할 수 있다면 동일한 공유 메모리 영역에 접근할 수 있습니다. 언어 간 호환은 데이터 포맷 일치를 주의하세요.

🔚 WinAPI로 구현하는 고성능 IPC의 핵심 전략

이번 글에서는 WinAPI를 활용한 프로세스 간 통신 방식 중에서도 가장 빠르고 효율적인 방법 중 하나인 메모리 맵 방식을 집중적으로 다뤄봤습니다.
CreateFileMapping과 MapViewOfFile을 통해 서로 다른 프로세스가 메모리를 공유할 수 있으며, 코드도 비교적 간단하고 구조도 직관적이죠.
특히 문자열 외에도 구조체나 바이너리 데이터까지 공유 가능하다는 점에서 실무 활용도가 매우 높습니다.

다만 공유 메모리 방식은 동기화와 권한 설정에 따른 리스크도 존재하기 때문에, 실무에 적용할 때는 보안 속성과 예외 처리를 철저히 고려해야 합니다.
이번 글의 실전 예제를 기반으로, 여러분도 직접 IPC 구조를 구현해보고 성능을 체감해보시길 추천드립니다.
이 글이 시스템 프로그래밍 또는 WinAPI 학습에 실질적인 도움이 되었기를 바랍니다.


🏷️ 관련 태그 : WinAPI, 프로세스간통신, 메모리맵, CreateFileMapping, MapViewOfFile, 공유메모리, IPC, 시스템프로그래밍, WindowsAPI, 소프트웨어아키텍처