File Descriptor
유닉스 시스템에서는 많은 것들을 파일로 관리한다. 정규 파일들뿐만 아니라 디렉터리, 소켓, 기타 입출력 장치들 모두 파일의 형태로 취급하는데, 이 파일들을 구분하기 위해 파일 디스크립터라는 개념을 사용한다.
우선 각각의 프로세스들이 실행될때 file descriptor table도 함께 생성된다. file descriptor table은 배열 형태로 관리가 되며, file descriptor table의 각 element는 Inode table의 특정 위치 또는 연결된 소켓을 가리킨다.
우리가 open을 통해 파일을 열거나, socket 함수를 통해 소켓을 생성하면 int 형태의 파일 디스크립터가 리턴된다. 이때 이 파일 디스크립터는 file descriptor table 상에서 해당 파일 또는 소켓이 할당받은 위치의 인덱스이다. 따라서 파일 디스크립터는 항상 양수 값을 가지며, 파일을 정상적으로 열지 못하거나 소켓을 연결하지 못한 경우 -1을 예외적으로 리턴한다.
프로세스에서 소켓을 열거나 파일을 열 때 할당되는 파일 디스크립터는 항상 3부터 시작한다. 이는 0, 1, 2가 시스템 상 먼저 예약되어 있기 때문이다. 0, 1, 2에 예약되어 있는 정보는 아래와 같다.
File Descriptor | Name | unistd.h | stdio.h |
0 | Standard input | STDIN_FILENO | stdin |
1 | Standard output | STDOUT_FILENO | stdout |
2 | Standard error | STDERR_FILENO | stderr |
위의 표와 같이 0, 1, 2는 표준 입출력과 관련된 파일들이다. 예를 들어 우리가 printf 함수를 통해 문자열을 콘솔에 출력하는 작업은 1번 파일 디스크립터에 문자열을 쓰는 것과 다르지 않다는 것이다.
따라서 파일 디스크립터는 항상 3번부터 할당이 되고, 할당 요청이 들어오면 아직 할당되지 않은 파일 디스크립터 중 가장 작은 값을 할당해 준다.
file table은 각 프로세스마다 따로 가지고 있으므로, 서로 다른 프로세스에서 같은 파일을 참조한다 해도 각각 다른 파일 디스크립터를 가질 수 있고, 다른 프로세스에서 같은 파일 디스크립터를 가지고 있어도 다른 파일을 참조할 수 있다.
File table
그렇다면 file table에는 어떤 정보가 들어있는걸까? 파일 테이블에는 각 파일의 구조체를 가리키는 포인터가 저장되어 있다.
그림에서 file descriptor의 3번과 4번 위치에는 각각 파일의 구조체를 가리키는 포인터가 담겨있다. 이 파일 구조체들에는 파일의 위치와, 파일이 참조된 횟수를 나타내는 ref_cnt 변수가 있다. 추가적으로 Inode table에서 파일의 위치를 가리키는 포인터 또한 존재한다.
File descriptor table은 프로세스 당 하나씩 존재하지만, 그림에 나타난 Open file table은 모든 프로세스가 공유한다.
위와 같은 방식으로 파일 입출력시 프로그램에서는 파일을 파일 식별자로 추상화하여 I/O를 진행한다.
'Computer System' 카테고리의 다른 글
[Computer System] 동적 메모리 할당기 (0) | 2023.04.13 |
---|---|
[Computer System] 동적 메모리 할당 (0) | 2023.04.12 |