파일디스크립터

2022. 12. 18. 14:38자바멘토링

파일 디스크립터(File Descriptor)란?

 

리눅스와 유닉스에서는 시스템을 전부 파일로 처리하여 관리한다. (하드웨어 등 모든 장치도 포함)

시스템에서 프로세스가 파일에 접근하기 위한 방법으로 파일 디스크립터(FIle Descriptor)라는 핸들이 필요하다.

 

해당 파일을 open할때( 해당파일에 접근할 때 ) 파일 디스크립터는 0부터 N까지 즉, 음수가 아닌 0부터 차례대로 숫자를 부여받으며,

0, 1, 2는 프로세스가 메모리에서 실행을 시작할때 기본적으로 할당되는 파일 디스크립터이다.

 

 

 

 

  기본적으로 할당받는 파일 디스크립터

  0번 : 표준 입력(Standard Input)      / STDIN_FILENO

 

  1번 : 표준 출력(Standard Output)   / STDOUT_FILENO

 

  2번 : 표준 에러(Standard Error)      / STDERR_FILENO

 

 

그러므로 우리가 생성하는 파일 디스크립터들은 3번 부터 차례대로 할당받게된다.

쉽게 생각하면, 파일 디스크립터는 파일을 다루기 위해서 해당파일의 주소를 참조하여 접근하는 형태라고 생각하면 된다.

 

1. 파일 디스크립터 확인

 

 

#include<stdio.h>

#include<stdlib.h>

#include<fcntl.h>

#include<unistd.h>

int main()

{

        int fd;

        if( (fd = open("test.txt", O_RDONLY)) < 1 )

  {

                printf("open() error");

                exit(1);

        }



        printf("FD : %d\n", fd); 



        close(fd);

        return 0;

}

 

 

 

▶ 실행결과

 

 

 

 

 

파일 디스크립터가 단순히 숫자인 이유는 프로세스가 유지하고 있는 file descriptors 테이블의 인덱스이기 때문이다. 

일 오픈 or 소켓생성 시 부여되는 파일 디스크립터는 3부터 시작한다.

프로세스가 실행 중에 파일을 Open 하면 커널은 해당 프로세스의 파일 디스크립터 숫자 중에 사용하지 않는 가장 작은 값을 할당해 준다.

그 다음 프로세스가 열려있는 파일에 시스템 콜을 이용해서 접근할 때, 파일 디스크립터 값을 이용해 파일을 지칭할 수 있다. 

사진 출처 https://dev-ahn.tistory.com/96

file descriptors 테이블의 각 항목은 FD 플래그 파일 테이블로의 포인터를 가지고 있다.

이 포인터를 이용하여 FD 를 통해 시스템의 파일을 참조 할 수 있는 것이다.

프로세스는 이런 FD 테이블과 파일 테이블의 정보를 직접 고칠 수 없으며, 반드시 커널을 통해서 수정을 해야 한다.

 

 

FD의 최대값은 OPEN_MAX라는 값이다.

즉, 하나의 프로세스 당 최대 OPEN_MAX개의 파일을 열 수 있다. OPEN_MAX 값은 플랫폼에 따라 다르다.

최대 파일 갯수는 다음의 방법을 사용하여 알아볼 수 있다. 

 

OPEN_MAX는 단일 프로그램에 허용되는 최대 열린 파일 수를 정의하는 상수다.

Unix 시스템에서 C언어의 OPEN_MAX는 limits.h에 정의돼있다.

OPEN_MAX와 FOPEN_MAX와 _SC_OPEN_MAX는 조금씩 다르다고 한다. (출처)

 

방법 1) 터미널에서 getconf 명령어로 확인

getconf OPEN_MAX


/* 결과값 */
2560

 

방법 2) <unistd.h>의 sysconf() 함수로 확인

#include <unistd.h>
#include <stdio.h>

int	main(void){
	int	max;

	max = sysconf(_SC_OPEN_MAX);
	printf("%d\n", max);
	return(0);
}


/* 컴파일 후 결과값 */
2560

 

결론: 리눅스 혹은 유닉스 계열의 시스템에서 프로세스(process)가 파일(file)을 다룰 때 사용하는 개념으로, 프로세스에서 특정 파일에 접근할 때 사용하는 추상적인 값이다.
 파일 디스크럽터는 일반적으로 0이 아닌 정수값을 갖는다. 
 
프로세스가 실행 중에 파일을 Open하면 커널은 해당 프로세스의 파일 디스크립터 숫자 중 사용하지 않는 가장 작은 값을 할당해준다. 그 다음 프로세스가 열려있는 파일에 시스템 콜을 이용해서 접근할 때, 해당파일의 주소(FD)를 참조하여 접근하는 가능하다

또한 파일 디스크립터는 FD의  최대값은OPEN_MAX값인데 이것이 OS 마다 다르고 그 이상은 열수 없다

이로인한 메모리 누수가 발생 할수도 있는데, 그 이유는 main메소드 끝나면 stack에 값을 날라가지만 파일 디스크립터는 커널의 영역 이고 gc는 jvm이라는 사용자 프로그램 영역이깅에 사용자 프로그램에서 커널을 제어 할 수 없다. 
그래서 명시적으로 close를 해주지 않을시 자원이 낭비되면서 시스템이 다운 되는 상황이 발생 할 수있다.

 

'자바멘토링' 카테고리의 다른 글

Future을 이용한 비동기 프로그래밍  (0) 2023.01.01
리플렉션을 이용한 json 직렬화  (0) 2022.12.28
리플렉션  (0) 2022.12.15
Try - With - Resource  (0) 2022.12.04
추상클래스  (0) 2022.12.03