파일 디스크립터는 운영 체제에서 파일이나 입출력 자원을 식별하고 관리하기 위한 핵심적인 개념이다. 파일 디스크립터는 보통 정수 값으로 표현되며, 프로세스가 파일 시스템의 파일, 소켓, 파이프 등과 같은 자원에 접근할 때 사용된다.
파일 디스크립터는 운영 체제의 커널에서 유지 관리되며, 각 파일 디스크립터는 파일 테이블의 엔트리를 가리킨다. 파일 테이블은 파일 디스크립터와 파일 시스템 객체(예: 파일, 디렉터리) 간의 매핑을 유지하는 데이터 구조이다. 이를 통해 프로그램이 파일을 열거나, 읽거나, 쓰거나, 닫는 등의 작업을 할 수 있게 된다.
프로세스가 파일을 열면, 운영 체제는 파일 테이블에 엔트리를 생성하고, 해당 엔트리를 가리키는 파일 디스크립터를 프로세스에 반환한다. 이후 프로세스는 이 파일 디스크립터를 사용하여 파일에 대한 작업을 수행할 수 있다. 예를 들어, 파일 읽기(read) 또는 쓰기(write) 작업을 할 때 파일 디스크립터를 사용하여 어떤 파일을 대상으로 하는지 운영 체제에 알린다.
파일 디스크립터는 몇 가지 특별한 값을 가질 수 있다. 예를 들어, 일반적으로 표준 입력은 파일 디스크립터 0번, 표준 출력은 파일 디스크립터 1번, 표준 오류는 파일 디스크립터 2번으로 할당된다. 이러한 표준 파일 디스크립터는 모든 프로세스가 기본적으로 사용할 수 있는 파일 디스크립터이다.
# 출력과 에러 병합
make > build_log.txt 2>&1
# 출력과 에러 분리
$ find / -name "*.txt" > found_files.txt 2> search_errors.log
파일 디스크립터의 중요한 특징 중 하나는 한 프로세스 내에서 동일한 파일을 여러 번 열 경우, 각 열기 작업마다 다른 파일 디스크립터가 반환된다는 것이다. 이는 각 파일 디스크립터가 별도의 파일 상태(예: 파일 오프셋, 접근 모드 등)를 유지할 수 있게 하기 위함이다. 반면, 부모 프로세스가 자식을 포크(fork)할 때, 파일 디스크립터는 상속된다. 따라서 부모와 자식 프로세스는 동일한 파일 디스크립터를 공유할 수 있으며, 이는 파일 오프셋 등의 상태도 공유됨을 의미한다.
파일 디스크립터는 자원이기 때문에 사용이 끝나면 반드시 닫아야 한다. 파일 디스크립터를 닫지 않으면 자원이 해제되지 않고 누수(leak)가 발생할 수 있다. 이는 특히 많은 파일을 여는 애플리케이션에서 중요한데, 파일 디스크립터의 최대 수 제한이 있기 때문이다. 파일을 닫는 작업은 보통 close
시스템 호출을 통해 이루어진다.
요컨대, 파일 디스크립터는 파일 시스템과의 상호작용을 관리하는 중요한 메커니즘이다. 운영 체제는 파일 디스크립터를 통해 파일을 식별하고 접근을 제어하며, 프로세스는 파일 디스크립터를 사용하여 파일 시스템 자원에 효율적으로 접근할 수 있다. 파일 디스크립터의 올바른 관리는 시스템 자원의 효율적인 사용과 안정성 유지에 필수적이다.