Windows/Windows API

shared memory

aucd29 2013. 10. 1. 19:00
http://wwwi.tistory.com/63

프로세스간 통신이 되면 여러가지로 편리한 점이 있다.
프로세스간 통신을 하는 간단한 방법으로는 메모리 맵 파일이 있다.

어떤 프로세스에서 쓰고 있는 메모리는 가상 메모리로 그 어드레스는 가상 메모리의 어드레스이다.
따라서 다른 프로세스에 있어서는 의미가 없는 어드레스이다.

어떤 프로세스에서 물리 메모리의 어드레스를 가상 메모리로 매핑하여 읽고 쓰면
다른 프로세스에서도 그 메모리에 대하여 읽고 쓰기가 가능하다.


파일 매핑을 이용한 프로스세간 통신 예제

◆ 공유 메모리 생성과 공유 메모리에 쓰기(서버)
[code]
#include <stdio.h>
#include <windows.h>
#include <conio.h>

#define    DATA_LEN    1024

LPSTR    lpMapping;

int main()
{
    BOOL    bEnd = FALSE;
    char    szData[DATA_LEN];
    char    szNo[8];
    HANDLE    hMemMap = NULL;

    while (1)
    {
        printf("1. 공유 메모리 데이터 쓰기\");
        printf("0. 종료\");
        printf("원하는 작업의 번호를 눌러주세요.");

        gets(szNo);

        switch (szNo[0])
        {
            case '1':

                // 매핑 파일 만들기
                hMemMap = CreateFileMapping((HANDLE)0xFFFFFFFF,
                                NULL,
                                PAGE_READWRITE,
                                0,
                                DATA_LEN,
                                "MemoryMapTest");

                if (hMemMap == NULL)
                    return -1;

                if (GetLastError() == ERROR_ALREADY_EXISTS)
                    printf("이미 매핑 오브젝트가 있음.\n");

                // 파일에 매핑하기
                lpMapping = (LPSTR)MapViewOfFile(hMemMap,
                                FILE_MAP_ALL_ACCESS,
                                0,
                                0,
                                0);

                if (lpMapping == NULL)
                    return -2;

                printf(" === 매핑 파일에 데이터 입력 ===\n");

                gets(szData);

                // 매핑 파일에 데이터 입력
                strcpy(lpMapping, szData);

                UnmapViewOfFile(lpMapping);

                break;
            case '0':
                bEnd = TRUE;
                break;
            default:
                printf("번호가 문제있음\n");
                break;
        }
        if (bEnd)
            break;
    }

    if (CloseHandle(hMemMap) == 0)
        printf("메모리맵 핸들 종료 실패\");
    else
        printf("메모리맵 핸들 종료 성공\");

    return 0;
}
[/code]

◆ 공유 메모리 열기와 공유 메모리의 데이터 읽기(클라이언트)

[code]
#include <stdio.h>
#include <windows.h>
#include <conio.h>

LPSTR    lpMapping;

int main()
{
    BOOL    bEnd = FALSE;
    char    szNo[8];
    HANDLE    hMapRead;

    while (1)
    {
        printf("1. 공유 메모리 데이터 읽기\n");
        printf("0. 종료\n");
        printf("원하는 작업의 번호를 눌러주세요.");

        gets(szNo);

        switch (szNo[0])
        {
            case '1':

                // 매핑 파일 열기
                hMapRead = OpenFileMapping(FILE_MAP_ALL_ACCESS,
                                FALSE,
                                "MemoryMapTest");

                // 파일에 매핑하기
                lpMapping = (LPSTR)MapViewOfFile(hMapRead,
                                FILE_MAP_ALL_ACCESS,
                                0,
                                0,
                                0);

                if (lpMapping == NULL)
                {
                    printf("읽기 실패\n");
                    CloseHandle(hMapRead);
                    return -1;
                }

                // 읽어들인 데이터 출력
                printf(lpMapping);

                if (UnmapViewOfFile(lpMapping) == 0)
                {
                    printf("\n읽기용 어드래스 매핑 실패\n");
                }
                else
                {
                    printf("\n읽기용 어드래스 매핑 성공\n");
                    lpMapping = NULL;
                }

                CloseHandle(hMapRead);

                break;
            case '0':
                bEnd = TRUE;
                break;
            default:
                printf("번호가 잘못\n");
                break;
        }
        if (bEnd)
            break;
    }

    return 0;
}
[/code]

콘솔로 프로젝트를 만들어 위 소스를 붙여 넣어
서버와 클라이언트 프로그램을 만든다.
서버 프로그램을 실행시켜 1을 선택하여
데이터를 입력한다.

클라이언트 프로그램에서 1을 선택하면
서버 프로그램에서 입력한 데이터를 참조 할 수 있다.