17.메모리 매핑

#.메모리 맵

유닉스 시스템이 제공하는 통신 기능은 크게 두가지로 구분할 수 있다.

 

1.동일한 시스템 안에 있는 프로세스 사이에서 통신을 수행하는 것

 

2.두번째는 서로 다른 시스템에서 수행하고 있는 프로세스 사이에서 통신으로 데이터를 주고 받는 것.

 

프로세스 간 통신 : 동일한 유닉스 시스템 안에서 수행 중인 프로세스끼리 데이터를 주고받는 것

 

예)

파이프(pipe) 같은 특수 파일을 이용하거나, 메모리 매핑이나 공유 메모리 같은 메모리 영역을 이용하는 방법이 있다.

또한 메시지 큐, 공유 메모리, 세마포어 등 유닉스 시스템 V에서 제공하는 IPC 방법이 있음.

 

네트워크를 이용한 통신 : 유닉스 시스템에서 네트워크를 이요한 통신은 TCP/IP 프로토콜을 기본으로 하고 있으며, 소켓 라이브러리를 이용한다.

 

#.메모리 매핑과 해제 

 

메모리 매핑은 파일을 프로세스의 메모리에 매핑하는 것이다. 즉, 프로세스에 전달한 데이터를 저장한 파일을 직접 프로세스의 가상 주소 공간으로 매핑한다. 

(read, write 함수를 사용안해도 됨!)

 

 *메모리 매핑

void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);

  • addr: 매핑할 메모리 주소 or null

  • len: 메모리 공간의 크기

  • prot: 보호 모드 (매핑한 데이터를 읽기만 할지, 쓰기나 실행도 허용할지)

  • flags: 매핑된 데이터의 처리 방법을 지정하는 상수

  • fildes: 파일 기술자

  • off: 파일 오프셋

prot에 사용할 수 있는 값은 상수로 정의되어 있으며, OR 연산자로 연결해 지정할 수 있다.

  • PROT_READ: 매핑된 파일을 읽기만 한다.

  • PROT_WRITE: 매핑된 파일에 쓰기를 허용한다.

  • PROT_EXEC: 매핑된 파일을 실행할 수 있다.

  • PROT_NONE: 매핑된 파일에 접근할 수 없다.

prot에 PROT_WRITE를 지정하려면 flags 인자에 MAP_PRIVATE를 지정하거나, 파일을 쓰기 가능 상태로 열어야 한다.

 

#.메모리 매핑 해제

munmap 함수는 mmap 함수를 사용하여 매핑한 메모리 영역을 해제한다. 메모리 매핑이 해제된 메모리 영역에 접근하면 오류가 발생한다. 

 

 int munmap(void *addr, size_t len);

munmap 함수는 addr이 가리키는 영역에 len 크기만큼 할당해 매핑한 메모리를 해제한다. munmap 함수로 매핑을 해제한 메모리 영역에 접근하면 SIGBUS 혹은 SIGSEGV 시그널이 발생시킴. munmap 함수는 수행을 성공하면 0을, 실패하면 -1을 리턴.

 

#.메모리 보호모드 변경

#include <sys/mman.h>

int mprotect(void *addr, size_t len, int prot);

매핑된 메모리의 보호 모드는 mmap 함수로 메모리 매핑을 수행할 때 초깃값을 설정한다.

 

#.파일 크기 조정

존재하지 않거나 크기가 0인 파일은 mmap 함수를 사용해서 메모리에 매핑할 수 없다. 프로그램에서 빈 파일을 생성했다면 mmap으로 메모리에 매핑하기 전에 파일의 크기를 확장해야 한다.

 

int truncate(const char *path, off_t length);

path에 지정한 파일의 크기를 length로 지정한 크기로 변경할 수 있다.

(성공하면 0을, 실패하면 -1)

 

int ftruncate(int fildes, off_t length);

fildes에 지정한 파일의 크기를 length로 지정한 크기로 변경할 수 있다.

(성공하면 0을, 실패하면 -1)

 

#.매핑된 메모리 동기화

유닉스 시스템은 메모리에 매핑된 파일의 내용을 백업 공간에 복사해둔다. 따라서 매핑된 메모리의 내용과 백업 내용이 일치하도록 동기화해야 한다. MAP_SHARED 모드로 매핑한 메모리 영역에 백업 저장 장치는 파일이고, MAP_PRIVATE 모드로 매핑한 영역의 백업 저장 장치는 스왑 공간이다.

 

 int msync(void *addr, size_t len, int flags);

msync 함수는 인자로 지정한 addr로 시작하는 메모리 영역에서 [addr + len]만큼의 내용을 백업 저장 장치로 기록한다. 

(성공하면 0을, 실패하면 -1)

 

*Flags 종류

MS_ASYNC: 비동기 쓰기 작업을 수행한다. msync 함수는 즉시 리턴하고, 함수가 리턴한 후 적절한 시점에 쓰기 작업을 수행한다.

MS_SYNC: 쓰기 작업을 완료할 때까지 msync 함수가 리턴하지 않는다. 메모리의 크기가 클 경우 비교적 시간이 걸릴 수 있다.

MS_INVALIDATE: 메모리에 복사되어 있는 내용을 무효화한다.

 


 

 #.메모리 매핑과 해제 예제

결과

 

 

#.파일의 크기를 페이지 크기만큼 증가시켜 메모리를 매핑하고, 매핑된 메모리에 문자열을 출력 예제

결과

 

 #.매핑된 메모리의 내용을 일부 수정하고, 동기화 함수를 사용해 백업파일을 동기화하는 예제

결과

 

#.파일을 부모 프로세스와 자식 프로세스가 공유하는 예제

결과

 

 

 

 

참고: 유닉스 프로그래밍(한빛 미디어)