Researcher to Developer

mmap, msync, stat - 메모리와 파일 시스템 관련 시스템 콜 본문

카테고리 없음

mmap, msync, stat - 메모리와 파일 시스템 관련 시스템 콜

Probe29 2021. 1. 3. 18:22
malloc 함수
heap 영역에 동적메모리를 생성시킨다.

1. malloc () 함수로 동적메모리를 할당할 수 있다.
2. free () 함수로 해당 메모리를 해제할 수 있다.

메모리 조작 함수 종류
strcmp, strcpy, memset

 


파일 처리 성능 개선 기법 중

메모리에 파일을 매핑하는 시스템 콜에 대해서 알아보자.


mmap

프로세스에서 파일을 읽을 때는 시스템콜 호출, 스케줄러 관여, 인터럽트 관여 등의
메커니즘 때문에 복잡하고 시간이 오래 걸린다.

이 때 mmap 을 사용하는데, 파일을 메모리 특정 공간에 매핑을 해놓는다.
그러면 프로세스는 파일을 처리하는 것이 아니라 메모리를 읽거나 쓰면서
복잡한 과정을 거치지 않아 성능이 향상된다.

 

헤더 파일과 코드 예제는 다음과 같다.

#include <sys/mman.h>
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset

mmap의 리턴값은 메모리가 매핑이 정상적으로 되면 해당 메모리 주소값이 리턴이 됨

 

1. [start+offset] ~ [start+offset+length]만큼의 물리 메모리 공간을 mapping할 것을 요청
2. size_t : 메모리의 얼마만큼의 길이를 쓸꺼냐
3. 보통 start : NULL 또는 0 사용
4. 보통 offset : mapping 되기 원하는 물리 메모리 주소로 지정
5. prot : 보호 모드 설정, 권한 인자
 - PROT_READ(읽기 가능) / PROT_WRITE(쓰기 가능) / PROT_EXEC(실행 가능) / 
   PROT_NONE(접근 불가)

6. flags : 메모리 주소 공간 설정
- MAP_SHARED(다른 프로세스와 공유 가능) / MAP_PRIVATE(프로세스 내에서만 사용 가능) /
  MAP_FIXED(지정된 주소로 공간 지정)

7. fd : device file에 대한 file descriptor

예들 들어
start 가 0다
length 가 5다
offset 이 10이라면 
start에서 10만큼 (offset 만큼) 떨어진 곳에서 5만큼(length) 영역이 파일에 매핑이 된다.





#mmap 동작 방식으로 이해하는 실제 메모리 동작

1. mmap 실행 시, 가상 메모리 주소에 file 주소 매핑 (가상 메모리 이해)
페이지 x번 부터 y번까지 할당됨
페이지 디렉토리 중 사용 디렉토리만 페이지 테이블을 구성한다.

 


2. 해당 메모리 접근 시, (요구 페이징, lazy allocation)
페이지 폴트 인터럽트 발생
OS에서 file data를 복사해서 해당 물리 메모리 페이지에 넣어준다.


3. 메모리 read 시 해당 물리 페이지 데이터를 읽으면 됨 (메모리 access 만 필요한 것)


4. 메모리 write 시 해당 물리 페이지 데이터 수정 후, 페이지 상태 flag 중 
dirty bit(알고리즘에 따라 이름이 바뀔 수 있음)를 1로 수정


5. 파일 close 시, mmap을 더 이상 사용하지 않을 때라던지,
mmap으로 매핑된 메모리를 파일에 싱크, 저장을 강제로 할 때 라던지 그 때
물리 페이지 데이터가 file에 업데이트 됨 → 성능 개선

mmap 을 이용하면 파일 access 빈도수가 굉장히 적기 때문에 성능이 많이 개선된다.

 




#mmap 장단점

장점
read, write 시 반복적인 파일 접근을 방지하여 성능 개선
mapping 된 영역은 파일 처리를 위한 lseek() 을 사용하지 않고 간단한 포인터 조작으로 탐색 가능 


단점
mmap은 페이지 사이즈 단위로 매핑
페이지 사이즈 단위의 정수배가 아닌 경우, 한 페이지 정도의 공간 추가 할당 및 남은 공간을
0으로 채워주게 된다.

페이지 단위로 매핑하기 때문에 추가공간이 필요하거나 공간 낭비가 있을 수 있다.





#mmap 해제

int munmap(void *addr, size_t length_

*addr 에 mapping된 물리 메모리 주소를 해제한다.
length : mapping된 메모리의 크기(mmap에서 지정했던 동일 값을 넣는다.)

 

 

 

#msync

메모리에 있는 값이 변경이 되면
해당 파일에 업데이트 해줘야 하잖아요??
이를 강제적으로 해주는 함수가


msync

mmap을 사용해 맵핑한 메모리 주소 영역에 대해 동기화를 하기 위한 함수

int msync(void *start, size_t length, int flags);

 

start : mman()을 통해 리턴 받은 메모리 맵의 시작 주소
length : 동기화를 할 길이. 시작 주소로 부터 길이를 지정하면 된다.
flags
MS_ASYNA : 비동기 방식, 동기화(Memory → File)하라는 명령만 내리고 결과에
                 관계 없이 다음 코드 실행 (따라서, 동기화가 완료 안된 상태로 다음 코드 실행 가능)
MS_SYNC :  동기 방식, 동기화(Memory → File)가 될 때까지 블럭 상태로 대기
MS_INVALIDATE : 현재 메모리 맵을 무효화하고 파일의 데이터로 갱신. 즉 File → Memory






#inode 방식 파일 시스템

기본 개념

프로세스 마다 pid가 존재하고 pid 별로 PCB가 존재한다.
이와 마찬가지로 파일도 파일마다 inode 값이 존재하고 inode 별로 구조체를 가지고 있다.

 

 

inode 구조체

Mode 파일 종류나 권한(rwx) 정보
Owner Info 소유자, 소유 그룹 정보
Size 파일 크기 정보
Timestamps 생성, 수정 등의 시간 정보
Direct blocks (12개) 직접적으로 주소를 가리킴
Single indirect
Double indirect
Triple indirect




stat

inode 정보를 한 번에 가져올 수 있는 시스템 콜 

inode 메타 데이터

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *path, struct stat *buf);
int fstat(int filedes, struct stat *buf);

inode 메타 데이터 - stat 구조체 일부분

struct stat {
dev_t     st_dev;         / ID of device containing file
ino_t      st_ino;         / inode number
mode_t   st_mode;     / 파일 종류 및 접근 권한
nlink_t    st_nlink;       / 이 구조체에 hardlink 된 횟수
uid_t      st_uid;        / 파일 owner
gid_t      st_gid;        / group ID of owner
dev_t     st_rdev;       / device ID (if special file)
off_t      st_size;        / 파일 크기(bytes)
blksize_t  st_blksize;   / blocksize(4KB) for file system I/O
blkcnt_t   st_blocks;   / number of 512B blocks allocated 
time_t    st_atime;     / time of last access
time_t    st_mtime;    / time of last modification
time_t    st_ctime;     / time of last status change
};