1. mmap이란?
mmap(2)는 메모리의 내용을 파일이나 디바이스에 대응(mapping)하기 위해서 사용하는 시스템 호출이다.

2. 메모리관리와 mmap
각각의 프로세스는 프로세스마다 다른 프로세스와 중복되지 않는 주소공간을 가지게 된다. 주소 공간은 최초 논리적인 3개의 세그먼트로 분할된다.
텍스트, 데이터와 스택이 그것이다. 텍스트 세그먼트는 읽기전용으로 프로그램의 명령을 포함하고 있다. 데이터와 세그먼트는 읽기, 쓰기가 모두 가능한 영역이다. 대부분의 시스템에서는 프로세스의 실행과 함께 커널에 의해서 스택 세그먼트가 자동으로 확장된다. 데이터 세그먼트의 경우는 malloc() 계열의 시스템골을 이용해서 확장하는 것이 가능하다. 텍스트 세그먼트의 경우 디버깅과 같은 제한된 환경에서 크기의 변경이 가능하다.
어쨌든 간에 프로세스 메모리는 기본적으로 다른 프로세스와 메모리와 공유되지 않는다. 이것은 프로세스의 데이터를 보호하기 위해서 반드시 필요한 기능이긴 하지만 다른 프로세스와 특정 데이터를 공유하기 위해서는 귀찮은 기능이 되기도 한다. 이 때문에 IPC를 사용하게 된다. mmap은 메모리의 특정 영역을 파일로 대응시킬수 있도록 도와준다. 파일을 시스템 전역적인 객체이므로 다른 프로세스에서 접근가능하도록 할 수 있으며, 이러한 mmap의 특징때문에 IPC 용도로 사용가능하다.
※ mmap 이 IPC 용도로 사용가능하지만 IPC 설비는 아니다.
mmap은 프로세스의 주소공간을 파일에 대응시킨다. 파일은 운영체제 전역적인 자원이므로 당연히 어렵잖게 다른 프로세스와 공유해서 사용할 수 있을 것이다.

3. mmap의 활용용도
메모리의 내용을 파일에 대응시켜 얻을 수 있는 이익을 생각해보자. 그러면 mmap의 활용 용도를 결정할 수 있을 것이다.
1. 메모리의 내용을 파일에 대응시킬 수 있다면 프로세스간 데이터의 교환을 위한 용도로 사용가능할 것이다. 프로세스간 공유하고자 하는 데이터를 파일에 대응시키고 이것을 읽고 쓰면 된다. 물론 접근제어를 해줘야 하겠지만 말이다.
2. 메모리의 내용을 파일에 직접 대응시킨다면 성능향상을 생각할 수 있을 것이다. 고전적인 방법은 파일지정자를 얻어서 직접 입출력하는 방식으로 open, read, write, lseek와 같은 함수를 이용한다. 이러한 함수의 사용은 당연하지만 상당한 비용을 지불해야 하는데, mmap을 이용하면 비용을 줄일수 있다.

4. mmap 설명
mmap은 다음과 같이 선언되어 있다.
#include <sys/mmap.h>

#ifdef _POSIX_MAPPED_FILES
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *start, sizet_t length);
#endif

mmap 사용 예
handle = open(fname, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
mmap((void*)0, statbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, handle, 0);

mmap 함수는 start부터 length까지의 메모리 영역을 열린파일 fd에 대응한다.
대응할 때 파일의 위치를 지정할 수 있는데 이것은 offset을 통해서 이루어진다.
prot는 파일에 대응되는 메모리 영역의 보호특성을 결정하기 위해 사용된다. 메모리영역과 파일이 서로 대응되기 때문에 파일에 대한 어떠한 작업이 메모리영역에 직접적인 영향을 미칠 수 있기 때문이다. prot는 다음과 같은 플레그(flag)를 제공한다.
  1. PROT_EXEC : 페이지(page)는 실행될 수 있다.
  2. PROT_READ : 페이지는 읽혀질 수 있다.
  3. PROT_WRITE : 페이지는 쓸 수 있다.
  4. PROT_NONE : 페이지를 접근할 수 없다.

flags는 대응되는 객체의 형식을 지정하기 위해 사용한다. 이 flag에 어떤 값을 사용하느냐에 따라서 대응된 페이지를 다른 프로세스와 공유하거나 단지 생성한 프로세스만 사용할 수 있도록 지정할 수 있다.

  • MAP_FIXED
  • MAP_SHARED 대응되는 객체를 다른 프로세스도 공유할 수 있게 만들어준다. 프로세스들은 객체에 대해서 동등한 권한을 가지게 된다. 그렇다면 객체 접근에 대한 동기화를 시켜줄 필요가 있는데, 이를 위해서 msync와 munmap가 사용된다.
  • MAP_PRIVATE

mmap를 사용할 때 반드시 MAP_PRIVATEMAP_SHARED둘중 하나를 사용해야 한다.

위의 flag는 POSIX.1b에 정의된 표준적인 것들인데, 리눅스는 몇 가지 표준적이지 않은 flag를 제공한다. 이들 플레그는 man페이지를 참고하기 바란다.
mmap가 성공적으로 호출되면 메모리 대응된 장소에 대한 주소를 리턴 받는다. 우리는 이 값을 이용해서 메모리관련 작업을 하게 된다.

memcpy

memcpy
메모리 영역 복사

1. 사용법

#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);


2. 설명
memcpy는 메모리 영역 src를 dest로 n 바이트 복사한다. 메모리 영역은 겹쳐지지 않는다.
만일 메모리 영역을 겹쳐서 사용하길 원한다면 memmove를 사용한다.

memcpy() 함수는 포인터 dest 를 반환한다

+ Recent posts