mmap : 메모리를 파일처럼

mmap은 memory map 의 줄임말이다. 메모리의 특정 영역을 파일 디스크립터로 인식하게 만드는 것이다.

map or unmap files or devices into memory
메모리 영역을 파일이나 디바이스로 인식하게 합니다

– manpage of mmap

사용

void * mmap(void *start, 
           size_t length, 
           int    prot, 
           int    flags, 
           int    fd, 
           off_t  offset);

여기서 의미가 있는 건 Length, Prot (Protection), Flag 뿐이다.

  • Start 는, Kernel이 아무 곳이나 지정해도 좋다면 NULL을 입력한다.
  • Offset 은, 보통 0으로 둔다. (MAP_ANONYMOUS 또는 MAP_ANON Flag가 있는 경우엔 무시된다)
  • Fd 는, 연결할 파일 디스크립터를 지정한다. (MAP_ANONYMOUS 또는 MAP_ANON Flag를 통해서 ‘파일로 사용하지 않는다’ 라고 한다면 -1을 넣어줘야 한다. (사실 안 넣어주고 무시해도 되지만 몇몇 구현에서는 넣어야 한다 카더라)

Protection

매핑된 메모리 영역의 사용 권한 같은 것을 정하는 것이라고 이해하자. 리눅스 파일 시스템의 권한과 비슷한 분류로 이해하면 더욱 쉽다. (물론 똑같지는 않지만)

  • PROT_NONE : 메모리 영역은 아무것도 할 수 없다.
  • PROT_READ : 메모리 영역을 읽을 수 있다.
  • PROT_WRITE : 메모리 영역을 쓸 수 있다.
  • PROT_EXEC : 메모리 영역이 실행될 수 있다.

이 때, 연결된 파일 디스크립터의 모드와 절대 충돌해서는 안 된다. 예를 들어 파일 디스크립터를 획득할 때는 w+ 라고 해놓고 여기서 PROT_READ 라고 하면, 예상치 못한 무언가가 일어나지 않을까?

메모리 영역의 보호에 관련된 자세한 내용은 여기를 참고하자.

Flag

Flag 사용 가능
커널
설명
MAP_SHARED 이 매핑을 다른 프로세스들이 공유할 수 있다. (실제 파일과 연결되어 반영된다. 하지만 자동으로 반영하지는 않고 msyncmunmap 을 호출해야 반영된다.)
MAP_PRIVATE 이 매핑을 다른 프로세스들과 공유하지 않는다. 실제 파일과도 연결되지 않으므로, mmap 이후에 파일에 반영되는 변경 내역이 매핑된 영역에 반영되는지는 확신할 수 없다.
MAP_32BIT ~2.4.20, 2.6 첫 2GB 안에서 영역을 잡는다.
x86-64 프로그램에서만 사용이 가능하다.
(초기 64-bit 프로세서에서는 context-switch 비용 절감을 위해 사용할 수 있는 옵션이겠지만, 지금은 그렇지 않으므로 굳이..)
MAP_ANONYMOUS
MAP_ANON
파일 디스크립터로 인식하지 않는다. fd와 offset은 무시되지만, 몇몇 구현에서는 fd를 반드시 -1로 입력해야 한다.

※ SHARED와 같이 사용하려면 Kernel Version 이 2.4 이하여야 한다.

 

헉헉… 아래에 더 있는데 여기까지만 해야겠다. 내가 사용하고자 하는건 사실 ANONYMOUS Flag 만 있으면 되는데 말이지.