고급 파일입출력

Jongwon·2021년 12월 8일
0

Linux Programming

목록 보기
13/25

Scatter-Gather I/O(Vector I/O)

메모리 버퍼에 흩어져있는 데이터를 한번에 모아서 파일에 write하거나, 파일에서 읽어온 데이터를 흩어져있는 버퍼에 전달함.

  • 분산된 자료를 쉽게 입출력할 수 있다.
  • 다수의 선형 입출력을 하나의 벡터 입출력(시스템 호출)으로 연산할 수 있다.
  • 흩어진 자료 입출력이 원자적으로 처리된다.

<sys/uio.h> 헤더

struct iovec {
	void *iov_base;
	size_t iov_len;
}
이 정의되어 있다. 이 구조체는 각 버퍼 하나를 의미한다.
  • ssize_t readv(int fd, const struct iovec *iov, int count)
  • ssize_t writev(int fd, const struct iovec *iov, int count)
    실제 R/W한 바이트 개수 반환, -1은 에러


I/O Multiplexing

여러 디바이스에서 입력을 기다리는 것.

  • Non-blocking read로 polling하기 : 데이터가 없어도 계속 return하므로, calling 계속해야함
  • 쓰레드 사용 : 하나의 쓰레드엔 하나의 디바이스만 기다릴 수 있음
  • 다중 입출력 함수 사용 : select, poll, epoll 함수
  • int epoll_create(int size) 최대 size개의 event를 담을 epoll을 만듬, epollfd반환
  • int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) event기다릴 fd 등록
  • int epoll_wait(int epfd, struct epoll_event *event, int maxevnets, int timeout) epoll을 기다림
Level Trigger 와 Edge Trigger

입력이 100개 있고, 50개에 대한 event가 처리된 이후에 대하여..
- Level Trigger : Default Mode로, 남아있는 입력이 있다면 다시 이벤트 발생
- Edge Trigger : epoll_event의 events에 EPOLLET 옵션을 줘서 설정가능하다.
		 남아있는 입력에 대해서는 관심이 없고, 새로운 이벤트가 오는 상태변화 있을때만 동작

Mapping

파일을 메모리에 바로 매핑하는 방식이다. mmap을 사용하면 파일을 읽어나 쓸때 read, write 함수를 호출할 필요없이 메모리에서 직접 r/w를 진행할 수 있다. 이 방식은 버퍼에 넣어두고 호출해야하는 read, write에 비해 성능이 뛰어나다.
운영체제가 가상 메모리의 빈 공간에 파일을 mapping한다. 따라서 System file Table의 reference count가 1 증가하고, 파일 디스크립터를 close해도 계속 입출력이 가능해진다.

이때 mapping시 offset과 addr은 Page단위로 정렬되어야 한다.

Page
접근 권한과 동작방식이 독자적으로 유지되는 메모리의 최소 단위로 메모리 사상을 기본 구성 블록이다. 가상 메모리를 4KB를 쪼개어 당장 필요한 Page만 물리 메모리에 넣어 사용한다.

  • long page_size = sysconf(_SC_PAGESIZE)
  • int page_size = getpagesize()
  • int page_size = PAGE_SIZE

mapping의 장단점

  • 버퍼에 추가적인 복사를 방지할 수 있음
  • 문맥전환이 일어나지 않음
  • 프로세스간 데이터 공유가 수월해짐
  • 포인터 조절만으로 영역 탐색 가능, lseek()가 필요없다.
  • 메모리 mapping은 page단위로 되기 때문에 나머지는 낭비
  • 파일크기 변경 불가
  • 메모리 사상과 관련한 자료 구조는 overhead

<mman.h>

  • void mmap(void addr, size_t len, int prot, int flags, int fd, off_t offset)
    addr로 매핑해달라, NULL이거나 불가능한 주소면 커널이 임의로 할당, 실패시 MAP_FAILED반환
len : 매핑될 영역 크기
prot : 메모리 보호 정책, PROT_READ, PROT_WRITE, PROT_EXEC로, fd의 r/w/x flag와 충돌나면 안된다.
flags :
- MAP_FIXED(무조건 addr로)
- MAP_PRIVATE(다른 프로세스나 파일에 영향 미치지않게)
- MAP_SHARED(모든 프로세스가 사상 공유)
  • int munmap(void *addr, size_t len)
    0이면 성공, -1은 에러
profile
Backend Engineer

0개의 댓글