leebaek

[UNIX 프로그래밍] 9강 - 메모리 매핑 본문

수업 정리/UNIX 프로그래밍

[UNIX 프로그래밍] 9강 - 메모리 매핑

leebaek 2024. 11. 17. 18:03

  • memory mapping
  • memory mapping 해제
  • 보호 모드 변경
  • 파일 크기 변경
  • 매핑된 메모리 동기화

memory mapping

memory mapping: file을 프로세스의 memory에 mapping

#include <sys/mman.h>
void *mmap(void *addr, size_t len,m int prot, int flags, int fildes, off_t off);

 

- fildes가 가리키는 파일에서 off로 지정한 위치부터 len만큼의 데이터를 읽어 addr이 가리키는 메모리 공간에 매핑함

  • addr : 매핑할 메모리 주소
  • len : 메모리 공간의 크기
  • prot : 보호모드
    • PROT_READ : 읽기 허용
    • PROT_WRITE : 쓰기 허용
    • PROT_EXEC: 실행 권한
    • PROT_NONE: 접근 권한 없음
  • flags : 매핑된 데이터의 처리 방법을 지정하는 상수
    • MAP_SHARED : 변경 내용 공유
    • MAP_PRIVATE : 변경 내용 공유하지 않음
    • MAP_ANONYMOUS: 파일과 연결되지 않은 익명 매핑
  • fildes : file descriptor
  • off : file offset ( 페이지 크기의 배수 )

- 페이지 단위 메모리 매핑 실행

- 매핑된 영역을 벗어나면, SIGBUS, SIGSEGV 발생

#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    int fd;
    char *mapped;
    size_t len = 4096; // 매핑 크기 (4KB)

    // 파일 열기
    fd = open("example.txt", O_RDWR);

    // 파일 매핑
    mapped = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  
    // 파일 내용을 메모리처럼 사용
    printf("File content: %s\n", mapped);

    // 매핑 해제
    munmap(mapped, len);

    // 파일 닫기
    close(fd);

    return 0;
}

 


 memory mapping 해제

munmap()

#include <sys/mman.h>
int munmap(void *addr, size_t len); // addr은 mmap의 반환값

보호 모드 변경

 mprotect()

#include <sys/mman.h>
int mprotect(void *addr, size_t len, int prot);

 파일 크기 변경

 truncate()

#include <unistd.h>
int truncate(const char *path, off_t len);

int ftruncate(int fildes, off_t len);

 매핑된 메모리 동기화

 msync()

#include <sys/mman.h>
int msync(void *addr, size_t len, int flags);

 

 flags 인자

  • MS_ASYNC : 변경 내용을 비동기적으로 파일에 쓰기
    • 호출이 즉시 반환되어, 데이터쓰기는 백그라운드에서 진행
  • MS_SYNC : 변경 내용을 동기적으로 파일에 쓰기
    • 호출이 반환되기 전에 모든 변경 내용이 파일에 저장됨
    • 데이터 무결성 보장 가능
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main() {
    int fd;
    char *mapped;
    size_t len = 4096; // 매핑 크기 (4KB)

    // 파일 열기
    fd = open("example.txt", O_RDWR);
   
    // 파일 매핑
    mapped = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    
    // 메모리 내용 수정
    strcpy(mapped, "Hello, Memory Mapping!");

    // 메모리 동기화
    if (msync(mapped, len, MS_SYNC) == -1) {
        perror("msync");
    }

    // 매핑 해제
    munmap(mapped, len);
    close(fd);

    return 0;
}