Windows에서 리눅스의 Shared Memory와 유사한 구조는 메모리 맵 파일 (Memory-Mapped File) 입니다.
메모리 맵 파일은 두 프로세스 간의 데이터 공유를 위해 사용할 수 있으며, 파일의 내용을 메모리에 매핑하여 프로세스가 이를 공유하게끔 합니다. 이는 리눅스의 shm_open()와 mmap() 함수로 메모리를 공유하는 방식과 유사합니다. Windows에서는 CreateFileMapping()과 MapViewOfFile() 함수를 사용하여 메모리 맵 파일을 생성하고, 이를 통해 메모리에 데이터를 매핑하여 여러 프로세스 간에 공유할 수 있습니다.
이 방식을 사용하면 각 프로세스가 같은 메모리 영역을 볼 수 있어 효율적으로 데이터를 교환할 수 있으며, 주로 큰 데이터 집합을 공유하거나 IPC(Inter-Process Communication)를 구현할 때 사용됩니다.
struct KSEJONG_MEMREC {
Ubyte lock_flag; /* 메모리사용상태 */
Ubyte seq[4];
Ubyte seq_no[4];
Ubyte full_code[12];
Ubyte code[7];
Ubyte jmast[SZ_JMAST +1];
Ubyte jsise[SZ_JSISE +1];
Ubyte info[SZ_INFO +1];
Ubyte hando[SZ_HANDO +1];
Ubyte chegyul_cnt[2];
Ubyte danilsise[SZ_DANILSISE+1];
Ubyte danilchegyul[CNT_DANILCHEGYUL][SZ_TIMECHEGYUL + 1];
};
#define SZ_KSEJONG_MEMREC sizeof(struct KSEJONG_MEMREC)
#define OFF_KSESHM (SZ_KSEJONG_MEMREC * CNT_KSEJONG)
Windows에서 C 언어로 KSEJONG_MEMREC 구조체를 메모리 맵 파일을 통해 공유하는 예제를 구성해보겠습니다. 아래 코드는 KSEJONG_MEMREC 구조체를 정의하고, 메모리 맵 파일을 통해 데이터를 공유하는 예제입니다. 한 프로그램에서 데이터를 쓰고, 다른 프로그램에서 이를 읽을 수 있도록 작성하였습니다.
1. 구조체 정의 및 메모리 맵 파일에 쓰기
먼저, 메모리 맵 파일에 데이터를 쓰는 코드를 작성하겠습니다.
#include <windows.h> #include <stdio.h> #include <string.h> #define SZ_JMAST 20 #define SZ_JSISE 20 #define SZ_INFO 20 #define SZ_HANDO 20 #define SZ_DANILSISE 20 #define CNT_DANILCHEGYUL 5 #define SZ_TIMECHEGYUL 20 #define CNT_KSEJONG 10 // KSEJONG_MEMREC 구조체 정의 #pragma pack(push, 1) typedef struct { BYTE lock_flag; // 메모리 사용 상태 BYTE seq[4]; // 주소 BYTE seq_no[4]; // 신코드Seq BYTE full_code[12]; // 풀코드 BYTE code[7]; // 단축코드 BYTE jmast[SZ_JMAST + 1]; // 거래소 종목마스터 BYTE jsise[SZ_JSISE + 1]; // 거래소 종목시세 BYTE info[SZ_INFO + 1]; // 거래소 거래원정보 BYTE hando[SZ_HANDO + 1]; // 거래소 외국인한도 BYTE chegyul_cnt[2]; // 체결 갯수 BYTE danilsise[SZ_DANILSISE + 1]; // 시세 BYTE danilchegyul[CNT_DANILCHEGYUL][SZ_TIMECHEGYUL + 1]; // 체결 } KSEJONG_MEMREC; #pragma pack(pop) #define MEM_SIZE (sizeof(KSEJONG_MEMREC) * CNT_KSEJONG) int main() { // 메모리 맵 파일 생성 HANDLE hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MEM_SIZE, TEXT("KSEJONG_SharedMemory")); if (hMapFile == NULL) { printf("Could not create file mapping object (%d).\n", GetLastError()); return 1; } // 메모리 맵 파일에 대한 뷰 생성 KSEJONG_MEMREC* pBuf = (KSEJONG_MEMREC*) MapViewOfFile( hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, MEM_SIZE); if (pBuf == NULL) { printf("Could not map view of file (%d).\n", GetLastError()); CloseHandle(hMapFile); return 1; } // 데이터 초기화 및 쓰기 memset(pBuf, 0, sizeof(KSEJONG_MEMREC)); pBuf->lock_flag = 1; memcpy(pBuf->seq, "1234", 4); memcpy(pBuf->seq_no, "5678", 4); memcpy(pBuf->full_code, "FULLCODE1234", 12); memcpy(pBuf->code, "CODE123", 7); memcpy(pBuf->jmast, "MasterInfo", 10); memcpy(pBuf->jsise, "PriceInfo", 9); memcpy(pBuf->info, "TradeInfo", 9); memcpy(pBuf->hando, "HandoInfo", 9); pBuf->chegyul_cnt[0] = 1; pBuf->chegyul_cnt[1] = 2; memcpy(pBuf->danilsise, "PriceData", 9); memcpy(pBuf->danilchegyul[0], "TradeData1", 10); printf("Data written to shared memory.\n"); // 메모리 뷰 및 핸들 닫기 UnmapViewOfFile(pBuf); CloseHandle(hMapFile); return 0; } |
2. 메모리 맵 파일에서 데이터 읽기
다음은 메모리 맵 파일에 저장된 데이터를 읽는 코드입니다.
#include <windows.h> #include <stdio.h> #define SZ_JMAST 20 #define SZ_JSISE 20 #define SZ_INFO 20 #define SZ_HANDO 20 #define SZ_DANILSISE 20 #define CNT_DANILCHEGYUL 5 #define SZ_TIMECHEGYUL 20 #define CNT_KSEJONG 10 #pragma pack(push, 1) typedef struct { BYTE lock_flag; BYTE seq[4]; BYTE seq_no[4]; BYTE full_code[12]; BYTE code[7]; BYTE jmast[SZ_JMAST + 1]; BYTE jsise[SZ_JSISE + 1]; BYTE info[SZ_INFO + 1]; BYTE hando[SZ_HANDO + 1]; BYTE chegyul_cnt[2]; BYTE danilsise[SZ_DANILSISE + 1]; BYTE danilchegyul[CNT_DANILCHEGYUL][SZ_TIMECHEGYUL + 1]; } KSEJONG_MEMREC; #pragma pack(pop) #define MEM_SIZE (sizeof(KSEJONG_MEMREC) * CNT_KSEJONG) int main() { // 기존 메모리 맵 파일 열기 HANDLE hMapFile = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, TEXT("KSEJONG_SharedMemory")); if (hMapFile == NULL) { printf("Could not open file mapping object (%d).\n", GetLastError()); return 1; } // 메모리 맵 파일에 대한 뷰 생성 KSEJONG_MEMREC* pBuf = (KSEJONG_MEMREC*) MapViewOfFile( hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, MEM_SIZE); if (pBuf == NULL) { printf("Could not map view of file (%d).\n", GetLastError()); CloseHandle(hMapFile); return 1; } // 데이터 읽기 printf("Read from shared memory:\n"); printf("Lock Flag: %d\n", pBuf->lock_flag); printf("Seq: %.4s\n", pBuf->seq); printf("Seq No: %.4s\n", pBuf->seq_no); printf("Full Code: %.12s\n", pBuf->full_code); printf("Code: %.7s\n", pBuf->code); printf("Jmast: %.10s\n", pBuf->jmast); printf("Jsise: %.9s\n", pBuf->jsise); printf("Info: %.9s\n", pBuf->info); printf("Hando: %.9s\n", pBuf->hando); printf("Chegyul Cnt: %d %d\n", pBuf->chegyul_cnt[0], pBuf->chegyul_cnt[1]); printf("Danilsise: %.9s\n", pBuf->danilsise); printf("Danilchegyul[0]: %.10s\n", pBuf->danilchegyul[0]); // 메모리 뷰 및 핸들 닫기 UnmapViewOfFile(pBuf); CloseHandle(hMapFile); return 0; } |
설명
- 쓰기 코드는 CreateFileMapping으로 메모리 맵 파일을 생성하고 MapViewOfFile로 메모리 뷰를 얻습니다. 이후 구조체 데이터를 메모리에 씁니다.
- 읽기 코드는 OpenFileMapping을 통해 기존 메모리 맵 파일에 접근하고, MapViewOfFile로 메모리 뷰를 얻어 데이터를 읽어옵니다.
이 코드를 통해 Windows 환경에서 C 언어로 Shared Memory를 사용할 수 있습니다.
이 코드는 Windows API 함수(CreateFileMapping, MapViewOfFile, UnmapViewOfFile, CloseHandle 등)를 사용하기 때문에 추가적인 라이브러리 링크는 필요하지 않습니다. Windows API는 기본적으로 Windows 운영 체제에 포함되어 있으므로 별도의 라이브러리를 링크하지 않아도 됩니다.
Visual Studio와 GCC(MinGW) 모두 Windows API 함수가 기본적으로 포함되어 있어서, 별도의 라이브러리 옵션을 명시하지 않고도 컴파일할 수 있습니다.
gcc write_memory.c -o write_memory.exe
gcc read_memory.c -o read_memory.exe
'리눅스 > Ubuntu 18.04.5 LTS' 카테고리의 다른 글
아래 명령을 사용하여 모든 .cs 파일에서 아스키 코드 123 ({)을 제거할 수 있습니다. (0) | 2024.10.15 |
---|---|
Redis의 설정 파일(redis.conf)에서 maxclients 옵션을 사용하여 허용할 최대 클라이언트 연결 수를 설정할 수 있습니다. (0) | 2024.08.30 |
Linux에서 C# 프로젝트를 설정하고 빌드하는 과정(Console/Wpf) (0) | 2024.08.30 |
특정 폴더 일괄 지우기/특정 파일 일괄 지우기 (0) | 2024.03.26 |
(2024.01.16)Ubuntu 20.04 환경에서 한글.언어설정(?) (0) | 2024.01.21 |