mmap

이리·2023년 5월 20일
0

System Programming

목록 보기
1/3

mmap 용도

메모리의 내용을 파일, 디바이스에 대응(mapping)하기 위한 시스템 호출

각각의 프로세서는 프로세서간 중복되지 않는 주소공간을 가진다. 이때 주소공간은 텍스트(Code)영역, data영역, 힙(Heap)영역, 스택(Stack) 영역으로 나뉜다.

  • 텍스트(Code) : 프로그램 명령 코드 자체를 저장하는 메모리 영역으로, Hex(16진수) 파일이나 Bin(2진수) 파일이 저장되는 영역

  • 데이터(data) : 전역변수, 정적변수, 배열, 구조체 등이 저장되는 영역

  • 힙(Heap) : malloc(), new() 같은 동적인 메모리를 할당할 때 위치하는 메모리 영역

  • 스택(Stack) : 지역변수, 매개변수, 리턴값 등 잠시 사용되었다가 사라지는 임시 데이터를 저장하는 영역, 함수 호출 시 생성되고, 함수가 끝나면 시스템에 반환


프로세서는 프로세서간의 데이터 보호를 위해 다른 프로세서와 메모리를 공유하지 않는다 -> 즉, 공유에 불편이 잇따른다. 이러한 불편함을 해소하기 위해 IPC(Inter Process Communication)이 사용되는데 mmap 함수가 IPC용도로 사용될 수 있다.

mmap 의 특징

mmap는 메모리의 특정 영역을 파일로 대응시킬 수 있도록 도와준다.
여기서 파일은 시스템의 전역개체로 모든 프로세서가 접근할 수 있는 영역이다.
즉, 다시 말하면 파일객체를 이용하면 프로세서간 데이터 공유가 가능하다 !

프로세서의 주소공간을 파일에 대응하여
(1) 프로세서간 데이터 교환에 이용
(2) 파일을 통해 데이터가 한번에 전달되기 때문에 성능 향상
에 도움이 된다.

mmap 문법

mmap( 시작주소 , 길이 , prot , flag , fd , offset )

풀어 설명하자면, '시작 주소부터 길이까지 메모리 영역을 fd에 offset 에서부터 대응한다' 로 설명할 수 있다.

이와 반대로 메모리를 해제하는 방법으로는

munmap( 시작주소 , 길이 ) 

로 메모리를 즉시 해제할 수 있다.


mmap 사용 예제

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <fcntl.h>

#define FILE_MODE (S_IRUSR | S_IWUSR)

void mperr(char *call, int val){
    perror(call);
    exit(val);
}

int main( int argc, char *argv[]){
    int fdin, fdout;
    caddr_t src, dst;
    struct stat statbuf;

    if(argc != 3){
        mperr("usage : a.out <fromfile> <tofile>", 1);
    }

    if((fdin = open( argv[1], O_RDONLY)) < 0){
        fprintf(stderr, "cannot open %s for writing", argv[1]);
        exit(2);
    }

    if((fdout = open( argv[2], O_RDWR | O_CREAT | O_TRUNC, FILE_MODE )) < 0){
        fprintf(stderr, "cannot create %s for writing", argv[2]);
        exit(3);
    }

    if(fstat(fdin, &statbuf) < 0)
        mperr("fstat error",4);

    if(lseek(fdout, statbuf.st_size -1 , SEEK_SET) == -1)
        mperr("lseek error",5);
    
    if(write(fdout, "", 1)!=1 )
        mperr("write error", 6);

    if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0)) == MAP_FAILED)
        mperr("mmap error for input", 7);

    if ((dst = mmap(0, statbuf.st_size, PROT_WRITE, MAP_SHARED, fdout, 0)) == MAP_FAILED)
        mperr("mmap error for output", 8);
        
    memcpy(dst, src, statbuf.st_size);

    if(munmap(src, statbuf.st_size) != 0)
        mperr("munmap(src) error", 9);

    if(munmap(dst, statbuf.st_size) != 0)
        mperr("munmap(src) error", 10);
    
    exit(0); 
}

gcc 컴파일

gcc -o -c mmcp.o mmcp.c
gcc -o mmcp mmcp.o
./mmcp <fromfile> <tofile>

실행결과

우선 fromfile인 test.rtf 파일을 생성한다.

이후 gcc 컴파일을 통해 mmcp 를 실행하면

result 라는 새로운 파일이 생성되며 test 파일의 내용이 복사됨을 확인 할 수 있다.

0개의 댓글