개발지식/이것저것

파일디스크립터에 대하여(간단한 설명)

뜨거운 개발자 2022. 12. 19. 20:39

 

안녕하세요 조신입니다

오늘은 파일 디스크립터에 대해 이야기해보고 다음으로는 42서울 과제에서 get_next_line의 openmax값을 이용해 디펜스 하는 방법을 알려드리고자 합니다.

파일 디스크립터란 무엇인가

간단히 말해서 파일을 표현하는 번호입니다. 조금 더 자세히 말하자면 파일의 위치를 가리키는 곳을 가리키는 번호라고 생각하시면 되겠습니다.

파일 디스크립터 생성

open, creat, socket, accept 등의 함수로 open하면 fd라는 숫자값이 생깁니다. 이 값은 각 프로세스마다 독립적이며 프로세스마다 다른 파일 디스크립터 태이블을 가지고 있습니다.

배경

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

사용 이유

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

특징

어떤 파일을 열때 저희는 fd값을 할당 받습니다.

fd는 0부터 N 까지 음수가 아닌 값을 차례대로 숫자를 부여 받습니다. 다만 0,1,2의 경우는 기본할당 fd라고 부릅니다.

기본 할당 fd

0번 : 표준 입력

1번 : 표준 출력

2번 : 표준 에러

일반적인 사용자는 3번부터 fd값을 할당 받게 됩니다. 쉽게 생각하면 fd는 파일을 다루기 위해 해당 파일의 주소를 참조하여 접근하는 형태라고 생각하면 됩니다.

fd가 숫자인 이유

fd가 주소 값이라고 했는데 단순히 숫자인 이유는 프로세서가 유지하고 있는 fd table의 인덱스이기 때문입니다.

실행 중 open시 할당되는 fd의 경우는 3부터 할당되며, 프로세서가 실행 중에 커널은 해당 프로세서의 fd 숫자 중에 사용하지 않는 가장 작은 값을 할당해줍니다.

그 후 프로세스가 열려있는 파일에 시스템 콜을 이용해서 접근 할 때, fd의 값을 이용해 파일을 지칭할 수 있습니다.

fd table

fd table은 각 항목은 fd 플래그와 파일 태이블로의 포인터를 가지고 있습니다.

이 포인터를 이용해 fd를 이용해 시스템의 파일을 참조 할 수 있습니다.

프로세스는 이런 fd table과 file table의 정보를 직접 수정할수 없으며 반드시 커널을 통해 작업해야만 합니다..

즉 저희의 fd는 filetable에 접근 하기 위해 존재하고 file table에서 inode table로 접근 함으로써 저희가 원하는 접근이 일어나는 것 입니다.

 

 

그렇다면 0,1,2는 어디로 연결되어 있는가?

0, 1, 2 는 프로세스가 메모리에서 실행할 때 기본적으로 할당되는 fd인데 이것은 tty라는 곳에 연결이 되어있습니다.

tty란

tty는 간단하게 말해서 하나의 연결되어있는 작은 모니터 정도로 이해하시면 됩니다.

각 프로세스마다 다른 tty값으로 연결이 되어있는데 `write(0,"abc",3);` 이렇게 사용하나 write(1,"abc",3); write(2,"abc",3);

이렇게 사용을 해줘도 전부 실행 결과는 쉘에서 같은 abc를 출력하게 됩니다.

그 이유는 파일디스크립터는 기본적으로 파일을 가리키는 번호입니다. 하지만 0,1,2의 경우는 파일을 열지 않았는데도 그냥 사용을 하는 fd값입니다. 따라서 이 fd값이 가리키는 방향은 모니터입니다. 실제로 쉘에서 tty를 치게 되면 다음과 같이 현재 연결되어있는 가상모니터 즉  tty가 나오게 됩니다. 다만 이 값은 각 쉘에 따라서 다 다르게 할당 될 것입니다.

따라서 한 프로세스에서 fd 0,1,2의 경우 그 프로세스가 가리키는 화면 모니터로 나오게 되는 걸 구현 한 것입니다. 

fd의 최대 값

OPEN_MAX라는 값은 fd의 최대 값을 의미한다. 즉 하나의 프로세스 당 최대 OPEN_MAX개의 파일을 열 수 있다. OPEN_MAX값은 플랫폼에 따라 다릅니다. 하지만 제가 이야기 하고 싶은 부분은 저희 클러스터 맥 기준이며 다른 곳에서는 다르게 작동 할 수 있음을 미리 알려드립니다.

OPEN_MAX —get_next_line 보너스 힌트

많은 분들이 get_next_line에서 얼마나 오픈될 지 몰라서 링크드 리스트로 구현을 하십니다. 하지만 저는 배열로 처리를 하였습니다.

ulimits -a명령을 입력하면

이렇게 file descriptors값을 찾을 수 있습니다.

이렇게 값을 ulimits -n옵션을 주시면 최대 오픈 파일 디스크립터 값을 변경 할 수가 있습니다.

하지만…!

49152까지는 바뀌다가 저희 클러스터 맥 환경에서는 최대 값이 49152여서 49153으로는 값을 변경 할수 가 없다는 메세지가 나오게 됩니다.

 

728x90

'개발지식 > 이것저것' 카테고리의 다른 글

[비트연산]대소문자 변경을 비트연산으로 해보자.  (3) 2023.01.15
read 함수  (0) 2022.12.22
컴파일에 대하여(간략설명)  (0) 2022.12.19
UML다이어그램  (0) 2022.12.19
COM 기술  (0) 2022.12.19