메모리 매핑 파일
Multiprocess 간의 통신(IPC, Inter-Process Communication)은 서로 다른 프로세스가 데이터를 주고받거나 리소스를 공유하는 방법입니다. 운영체제에서 프로세스는 독립된 메모리 공간을 가지기 때문에 직접적으로 데이터를 공유할 수 없습니다. 따라서 IPC 기법을 사용하여 프로세스 간의 데이터를 전달하거나 동기화해야 합니다.
Linux 및 Unix에서 사용하는 다양한 IPC 방법들을 아래에 설명합니다.
메모리 매핑 파일 (Memory-Mapped File)
메모리 매핑 파일(Memory-Mapped File)
은 파일을 메모리에 매핑하여, 여러 프로세스가 파일 내용을메모리
처럼 접근할 수 있는 방식입니다.- 이를 통해 파일 기반 데이터 공유가 가능하며, 프로세스 간에 파일을 매개로 데이터를 주고받을 수 있습니다.
메모리 매핑 파일 동작
- mmap(): 파일을 메모리에 매핑하여 파일 내용을 메모리처럼 사용할 수 있게 합니다.
- munmap(): 매핑된 메모리를 해제합니다.
이 방식은 대용량 파일을 공유하거나, 디스크 입출력 성능을 최적화하는 데 사용됩니다.
메모리 맵핑 파일의 장점
- 빠른 파일 I/O:
- 파일의 내용을 메모리처럼 다루기 때문에, 파일을 읽거나 쓰는 데 있어 속도가 매우 빠릅니다. 특히, 대용량 파일을 처리할 때 유리합니다.
- 부분 로딩 (Lazy Loading):
- 메모리 맵핑을 사용하면 파일 전체를 메모리로 읽어들이지 않고, 필요한 부분만 메모리에 로드하여 처리할 수 있습니다. 이를 통해 메모리 사용을 효율적으로 관리할 수 있습니다.
- 페이지 캐싱 활용:
- 메모리 맵핑된 파일은 운영 체제의 페이지 캐싱 기능을 사용할 수 있습니다. 자주 접근하는 파일의 부분은 운영 체제가 캐시로 저장해 두고, 빠르게 읽을 수 있습니다.
- 프로세스 간 파일 공유:
- 여러 프로세스가 동일한 메모리 맵핑된 파일을 공유할 수 있습니다. 이를 통해 효율적인 IPC(Inter-Process Communication) 수단으로 활용할 수 있습니다. 예를 들어, 하나의 프로세스가 파일을 쓰고, 다른 프로세스가 파일을 동시에 읽을 수 있습니다.
- 단순한 파일 접근:
- 메모리 맵핑 파일을 사용하면 파일 내용을 메모리처럼 다룰 수 있기 때문에, 파일에서 데이터를 읽거나 쓸 때 별도의 입출력 함수가 필요 없고, 배열처럼 간단하게 접근할 수 있습니다.
메모리 맵핑 파일의 단점
- 메모리 자원 소모:
- 메모리 맵핑 파일은 가상 메모리에 파일을 매핑하므로, 대용량 파일을 매핑할 경우 많은 메모리 자원을 사용하게 됩니다. 특히 시스템에 물리적 메모리가 부족하면 성능이 저하될 수 있습니다.
- 동기화 문제:
- 여러 프로세스가 동시에 같은 메모리 맵핑 파일에 접근하면 동기화 문제가 발생할 수 있습니다. 락(lock)과 같은 동기화 메커니즘을 사용해야 합니다.
- 플랫폼 종속성:
- 메모리 맵핑 파일은 운영 체제에 종속적인 기능입니다. 따라서 플랫폼마다 동작 방식에 차이가 있을 수 있고, 서로 다른 운영 체제 간의 호환성 문제가 발생할 수 있습니다.
- 파일 크기 제한:
- 메모리 맵핑을 사용할 때는 프로세스의 가상 메모리 공간 크기에 따라 파일 크기가 제한될 수 있습니다. 특히, 32비트 시스템에서는 가상 메모리 주소 공간이 작아 대용량 파일을 매핑하기 어렵습니다.
메모리 맵핑 파일 C 언어 예제
다음은 POSIX 기반의 C 언어를 이용한 메모리 맵핑 파일 예제입니다. 이 코드는 파일을 메모리로 매핑하여 파일의 내용을 읽고, 그 내용을 출력하는 간단한 예제입니다.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
int main() {
const char *filepath = "example.txt"; // 메모리 맵핑할 파일
int fd = open(filepath, O_RDWR); // 파일 열기
if (fd == -1) {
perror("Error opening file");
return 1;
}
// 파일 크기 가져오기
struct stat file_stat;
if (fstat(fd, &file_stat) == -1) {
perror("Error getting file size");
close(fd);
return 1;
}
size_t file_size = file_stat.st_size;
// 파일을 메모리 맵핑
char *mapped = mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mapped == MAP_FAILED) {
perror("Error mmapping file");
close(fd);
return 1;
}
// 메모리 맵핑된 파일 내용 출력
printf("File content:\n%s\n", mapped);
// 파일 내용 수정 (메모리처럼 다룸)
strcpy(mapped, "Modified content using mmap!");
// 변경 내용을 파일에 기록
if (msync(mapped, file_size, MS_SYNC) == -1) {
perror("Could not sync the file to disk");
}
// 메모리 맵핑 해제
if (munmap(mapped, file_size) == -1) {
perror("Error unmapping file");
}
// 파일 닫기
close(fd);
return 0;
}
코드 설명
open()
: 읽기/쓰기 모드로 파일을 엽니다.fstat()
: 파일 크기를 알아내기 위해 사용합니다.mmap()
: 파일을 메모리로 매핑합니다. 여기서PROT_READ | PROT_WRITE
는 메모리에 대해 읽기/쓰기 권한을 부여하고,MAP_SHARED
는 파일을 공유 메모리로 매핑하는 옵션입니다. 이 옵션을 사용하면, 다른 프로세스에서도 해당 파일에 접근할 수 있습니다.- 메모리처럼 파일 내용을 수정:
strcpy()
를 사용해 메모리 맵핑된 파일의 내용을 수정할 수 있습니다. msync()
: 메모리 맵핑된 내용이 실제 파일에 기록되도록 동기화합니다.munmap()
: 메모리 맵핑을 해제하여 자원을 반환합니다.
메모리 맵핑 파일의 일반적인 사용 사례
- 대용량 파일 처리:
- 데이터베이스 시스템이나 파일이 매우 큰 경우, 메모리 맵핑을 통해 빠르고 효율적으로 데이터를 처리합니다.
- 다중 프로세스간 파일 공유:
- 여러 프로세스가 동일한 파일에 접근해야 할 때, 메모리 맵핑을 통해 파일을 메모리에 올려두고 프로세스 간 데이터를 공유할 수 있습니다.
- 실시간 데이터 처리:
- 실시간으로 데이터를 처리하거나 자주 변경되는 데이터를 관리할 때, 메모리 맵핑을 사용하여 지연 시간을 최소화할 수 있습니다. 예를 들어, 비디오 스트리밍이나 게임 개발에서 메모리 맵핑을 활용합니다.
메모리 맵핑 파일은 빠른 성능이 필요한 대용량 데이터 처리나 실시간 데이터 관리에 매우 유용한 방식입니다.
'Interview > OS' 카테고리의 다른 글
OS Delayed Write 지연 쓰기 (0) | 2024.09.28 |
---|---|
OS 페이징과 캐시 (0) | 2024.09.28 |
Multiprocess간 IPC 중 공유 메모리 (0) | 2024.09.28 |
OS Semaphore 세마포어 (0) | 2024.09.28 |
OS Race Condition (0) | 2024.09.27 |