리눅스 시스템에서는 모든 것이 파일로 취급된다. 파일뿐만 아니라 디바이스, 네트워크 연결, 디렉터리, 프로세스 역시 파일처럼 다룬다. 이때 시스템이 이러한 파일에 접근할 때 **파일 디스크립터(File Descriptor)**라는 개념을 사용한다. 파일 디스크립터는 비음수 정수(0 ~ OPEN_MAX)로, 운영 체제가 프로세스마다 부여하는 값이다.
파일 디스크립터는 프로세스에서 열린 파일들을 관리하는 테이블의 인덱스이다. 예를 들어, 일반적으로 표준 입력(0), 표준 출력(1), 표준 오류(2)가 기본적으로 할당된다. FD 테이블의 각 항목은 파일 디스크립터에 대한 플래그와 파일 테이블을 가리키는 포인터를 포함하고 있으며, 이 포인터를 통해 시스템은 파일을 참조할 수 있다.
중요한 점은, 프로세스는 FD 테이블이나 파일 테이블을 직접 수정할 수 없다. 이 작업은 반드시 커널을 통해서 이루어진다.
각 프로세스는 커널이 관리하는 **open file descriptor table(열린 파일 디스크립터 테이블)**을 가진다. 이 테이블은 각 열린 파일에 대한 제어 정보를 포함하고 있으며, 테이블의 각 엔트리는 다음과 같은 정보를 담고 있다:
하나의 파일 디스크립터가 하나의 열린 파일을 참조하지만, 여러 파일 디스크립터가 동일한 열린 파일을 참조할 수 있다는 특징이 있다. 이 경우, 두 개 이상의 파일 디스크립터가 동일한 파일을 가리키지만 서로 다른 오프셋을 가질 수 있다.
file.txt
파일을 열고 두 개의 파일 디스크립터(FD1, FD2)를 얻는다.file.txt
를 참조하지만, FD1은 파일의 처음, FD2는 파일의 다른 부분을 가리킨다.다시 한번 정리해보면, file.txt
파일을 열면 운영 체제는 해당 파일에 대한 정보를 open file descriptor table에 추가한다. 이때 파일 디스크립터가 테이블 내 인덱스로서 file.txt
파일을 가리킨다. 파일을 닫으면, 테이블에서 해당 파일 디스크립터의 항목이 사라지며, 더 이상 해당 파일에 접근할 수 없게 된다.
파일 디스크립터는 운영 체제가 파일, 디바이스, 프로세스 등 다양한 자원을 추상화하여 관리하기 위해 사용하는 중요한 개념이다. 이를 통해 하나의 프로세스가 파일을 읽고 쓰는 동작을 효율적으로 관리할 수 있으며, 커널을 통해 파일 디스크립터와 파일 간의 연결이 이루어진다.