ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [OS] File Descriptor
    ComputerScience/OS 2024. 3. 18. 20:30
    728x90

    pintOS 시스템 콜을 구현하던 와중 파일, 파일 디스크립터, 파일 디스크립터 테이블 등과 같은 피상적으로만 알고 있던 개념이 나왔다. 이에 대해 이들이 무엇이고 왜 사용되며, 어떻게 사용되는지 알아보아야 구현이 가능하다 생각해 정리를 한 번 하고 넘어가고자 한다.

    파일 디스크립터(File Descriptor)

    파일 디스크립터는 운영체제가 파일을 다루기 위해 사용하는 추상화된 핸들이다.

    즉, 파일이나 입출력 같은 복잡한 객체를 다룰 때 직접적인 세부 정보나 구현 방식 대신 간단한 식별자를 사용하는 것이다.

    정수로 표현되며, 운영체제의 파일 시스템 테이블에 있는 파일이나 입출력 리소스를 가리킨다.

    각 프로세스는 자신만의 파일 디스크립터 테이블을 가지고 있으며, 이 테이블을 통해 파일이나 기타 입출력 리소스에 접근한다.

    파일 디스크립터 테이블(File Descriptor Table)

    프로세스가 열고 있는 파일, 소켓, 파이프 등의 입출력 리소스에 대한 정보를 담고 있는 테이블이다.

    각 프로세스마다 고유한 테이블을 가지고 있으므로, 다른 프로세스의 리소스에는 접근할 수 없다.

    파일 디스크립터 테이블은 일반적으로 파일 디스크립터를 인덱스로 사용하여 리소스에 대한 정보를 검색한다.

    파일 디스크립터 테이블 관리 과정

    1. 프로세스 생성 시
      프로세스가 생성될 때 커널은 프로세스를 위한 파일 디스크립터 테이블을 초기화한다.
      초기화 파일 디스크립터 0, 1, 2는 표준 입력(stdin), 표준 출력(stdout), 표준 오류(stderr)로 자동 할당된다.
    2. 파일, 리소스 오픈
      프로세스가 파일이나 리소스를 열면 커널은 해당 리소스에 대한 파일 디스크립터를 생성하고 프로세스의 파일 디스크립터 테이블에 이 정보를 저장한다.
    3. 리소스 사용
      프로세스는 할당받은 파일 디스크립터를 사용하여 해당 리소스에 대한 입출력 작업을 수행할 수 있다.
    4. 리소스 종료
      프로세스가 리소스 사용을 마치고 'close' 시스템 콜을 호출하면, 커널은 해당 파일 디스크립터를 테이블에서 제거하고 해당 파일 디스크립터를 다시 사용할 수 있게 한다.
    5. 프로세스 종료
      프로세스가 종료되면, 커널은 프로세스에 할당된 모든 리소스를 해제파고 파일 디스크립터 테이블을 파괴한다.

    리눅스 운영체제에서 파일 디스크립터로의 접근 과정

    1. 파일 열기
      프로세스가 'open'과 같은 시스템 콜을 호출할 때, 파일의 경로와 작업 모드(읽기, 쓰기 등)를 지정한다.
      리눅스 커널은 이 요청을 처리하고 파일 시스템에서 해당 파일을 찾아 접근 권한을 확인한다.
    2. 파일 디스크립터 할당
      접근 권한이 확인되면 커널은 프로세스의 파일 디스크립터 테이블에서 사용되지 않는 가장 낮은 정수 값을 찾아 이 파일에 할당한다.
      이 정수 값이 파일 디스크립터이다.
    3. 리소스 접근
      프로세스는 반환받은 파일 디스크립터를 사용하여 'read', 'write', 'close'와 같은 다른 시스템 콜을 호출하여 파일에 대한 다른 입출력 작업을 수행할 수 있다.
      각 시스템 콜은 파일 디스크립터를 인자로 받아 해당 작업을 식별하고 실행한다.
    4. 파일 디스크립터 테이블 조회
      커널은 파일 디스크립터를 사용하여 프로세스의 파일 디스크립터 테이블을 조회한다.
      이 테이블은 열린 파일과 관련된 메타데이터(ex. 파일 포인터 위치, 접근 권한, 파일 상태 정보 등)를 포함한다.
    5. 작업 수행
      커널은 테이블에서 해당 파일 디스크립터에 해당하는 엔트리를 찾아 실제 파일 리소스에 대한 작업을 수행한다.
    6. 결과 반환
      작업이 완료되면 커널은 작업 결과를 프로세스에 반환한다. 예를 들어, 'read'는 읽은 바이트 수를. 'write'는 쓴 바이트 수를 반환한다.

    아직 감이 잘 안 잡혀서, 구현을 좀 더 해보면서 찾아봐야겠다.

Designed by Tistory.