파일 입출력 함수들은 응용 프로그램이 시스템 호출을 통해 직접적으로 운영체제에 서비스를 받도록 한다. 파일 입출력 함수에서 데이터는 page cache를 통해 큰 단위로 read와 write를 한다.
man page의 (2)라고 표시된 함수들은 모두 System Call 함수이고, 운영체제의 시스템 콜 인터페이스에 정의가 되어있다.
보조기억장치와 메인 메모리 사이의 속도차를 줄이기 위해 개발, 동적인 크기 지원
hit ratio = cache hit count / total reference count, 높을수록 좋다.
read ahead : 앞으로 접근이 예상되는 자원을 미리 읽어둠.
일부 자원의 참조확률이 올라가는 것
page writeback : page cache에 있는 쓰일 내용을 보조기억장치에 한번에 작성
file descriptor 번호 반환
open_flag
기본: O_RDONLY, O_WRONLY, O_RDWR
추가: O_APPEND, O_CREAT, O_DIRECT, O_EXCL, O_DIRECT, O_TRUNC, O_NONBLOCK, O_SYNC
O_DIRECT : 캐시에 저장안하고 바로 I/O
O_EXCL : 파일 생성 시 파일명 있으면 에러 반환
O_SYNC : 쓰기 연산마다 디스크 I/O 발생
mode_t mode
쓰기 실행 시, 권한 설정
open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode)와 동일
-1이면 에러, 0이면 성공
읽은 byte수 반환, nbytes보다 작으면 시그널에 의한 중단 or 파일끝, 반환안되면 프로세스 중단 후 대기중,
void *buf
읽은 데이터 저장할 버퍼
size_t nbytes
읽어들일 최대 byte 수)
정상 시 nbytes 반환(buf가 부족하면 NULL로 채움)
const void *buf
쓰기 위해 읽을 데이터
파일의 새로운 offset 반환
off_t offset
whence 기준 상대적 거리
whence
기준점: SEEK_END, SEEK_CUR, SEEK_SET
음수면 0으로 바꿔주고, 파일크기 넘기면 쓸 때 커짐
ssize_t pread(int fd, void *buf, size_t count, off_t pos)
ssize_t pwrite(int fd, void *buf, size_t count, off_t pos)
읽고 쓸 시작위치 지정하여 멀티쓰레드 지원, 그 외는 read(), write()와 같다
int fsync(int fd) 버퍼에 수정사항(메타데이터 포함)을 디스크에 저장
int fdatasync(int fd) 파일데이터만 바로 저장
void sync(void) 모든 변경을 적음
int ftruncate(int fd, off_t len)
int truncate(const chat* path, off_t len)
len길이 이후의 파일을 자르고, 0이면 성공, -1이면 실패
둘의 차이 : truncate는 open할 필요가 없음
사용하지 않는 가장 작은 fd의 엔트리 할당
newfd로 할당, newfd에 이미 있으면 엔트리 닫고 할당
새로운 fd 반환
redirection 기능을 하고, 기존 fd에 엔트리는 유지됨
따라서, system file table의 count는 2가 되고, inode의 count는 1유지
I/O 준비가 된 파일 디스크립터 번호 반환
int n는 세팅된 가장 큰 fd번호임을 알려주는 힌트이지만 의미 없다.
fd_set: 파일 디스크립터 집합, 각 집합의 인덱스(각 비트)를 매번 검사하며
1로 켜져있는 비트(기다릴 fd)들 중 하나라도 깨어나면 fd_set초기화 후, 깨어난 fd번호를 1로 다시 만들어서 찾음
하지만, fd전체를 매번 검사해야하기 때문에 낭비고, 커널이 항상 검사해야 하기 때문에 좋지 않다.
fd_set 세팅 매크로
FD_CLR(int fd, fd_set *set) : 해당 fd를 0으로 바꿈
FD_SET(int fd, fd_set *set) : 해당 fd를 1로 바꿈
FD_ISSET(int fd, fd_set * set) : 해당 fd가 세팅되있는지 확인
FD_ZERO(fd_set *set) : 모두 0으로 초기화
기다리기 직전 signal 설정을 하고 기다림, 나머지는 select와 동일
struct pollfd {
int fd;
short events; //기다리는 이벤트
short revents; //받은 이벤트, 커널이 세팅해줌
}
이 정의되어 있고, 각 multiplex할 fd마다 struct하나씩 만들면 됨.
pollfd 타입 배열이 nfds있다고 알려주고, event올 때까지 기다림