전체 상황을 이해하기 위해 파일 설명자를 사용하려고 합니다. 처음에 다음과 같은 파일 설명자가 있는 process1이 있다고 가정해 보겠습니다.
_process1_
| |
| 0 stdin |
| 1 stdout |
| 2 stderr |
|__________|
그런 다음 파일 설명자 1을 닫습니다.
close(1);
파일 설명자 1은 표준 출력으로 변환(지정)합니다.파일 구조커널에서파일 테이블 열기.
위의 코드를 사용하면 파일 설명자 1이 프로세스 테이블에서 제거되어 다음과 같이 됩니다.
_process1_
| |
| 0 stdin |
| 2 stderr |
|__________|
하지만 커널에서는 무슨 일이 일어나는가? FILE 구조가 stdout
해제되었습니까? stdout이 특수 파일(모니터)이고 다른 프로세스에서 사용될 수 있는 경우 어떻게 이것이 가능합니까? FILE 구조가 일반 파일(예: .txt)인 경우에는 어떻게 되나요? 다른 프로세스가 그러한 파일을 사용하고 있다면 어떻게 될까요?
답변1
파일 설명자 1은 커널의 열린 파일 테이블에서 stdout FILE 구조로 변환됩니다.
이것은 오해입니다. 커널의 파일 테이블은 사용자 공간 파일 구조와 아무 관련이 없습니다.
어쨌든 커널에는 두 가지 수준의 간접 참조가 있습니다. 참조 계산되는 파일 자체를 나타내는 내부 구조가 있습니다. 참조 횟수가 계산되는 "열린 파일 설명"이 있습니다. 그런 다음 참조 계산되지 않는 파일 핸들이 있습니다. 파일 구조는 inode 자체를 가리킵니다. 열린 파일 설명에는 열기 모드와 파일 포인터가 포함됩니다.
닫기를 호출하면 항상 파일 핸들을 닫습니다. 파일 핸들이 닫히면 열린 파일 설명의 참조 횟수가 감소합니다. 0이 되면 열린 파일 설명도 해제되고 파일 자체의 참조 횟수가 감소됩니다. 이 값이 0이 될 때만 커널의 파일 구조가 해제됩니다.
공유 리소스는 참조 계산되므로 한 프로세스는 다른 프로세스에서 사용 중인 리소스를 해제할 기회가 없습니다.
답변2
이 경우에는 많은 일이 발생하지 않습니다. stdin, stdout 및 stderr은 모두 동일한 파일 설명자의 복제본인 경향이 있습니다. 파일 설명자의 참조 카운터는 1씩 감소합니다. 프로그램을 실행하는 셸은 일반적으로 동일한 파일 설명자를 저장하므로 파일 설명자를 보존해야 합니다.
커널은 열려 있는 모든 파일(inode)의 참조 횟수를 유지합니다. 참조 횟수가 0보다 크면 파일은 유지됩니다. 열린 파일 핸들에 대해 별도의 카운터를 유지하고 싶습니다. 0에 도달하면 커널은 파일 핸들에서 사용하는 메모리를 해제할 수 있습니다.
파일에 대한 모든 참조(디렉토리 항목 및 파일 핸들)가 제거되면 파일 시스템 코드는 재사용할 inode를 표시합니다. 파일에 있는 모든 블록을 할당할 수 있습니다. 많은 파일 시스템에서는 inode가 해제될 때 inode의 블록 포인터를 지웁니다. 이로 인해 삭제된 파일을 복구하기가 어렵습니다. 디스크 업데이트는 버퍼링되어 나중에 완료될 수 있습니다.
답변3
귀하의 설명은 마지막 단락까지 정확합니다.
하지만 커널에서는 무슨 일이 일어나는가? stdout FILE 구조가 해제되었습니까? stdout이 특수 파일(모니터)이고 다른 프로세스에서 사용될 수 있는 경우 어떻게 이것이 가능합니까? FILE 구조가 일반 파일(
afile.txt
예를 들어)이라면 어떻게 될까요? 다른 프로세스가 그러한 파일을 사용하고 있다면 어떻게 될까요?
커널은 stdin/stdout/stderr에 대해 아무것도 모릅니다. 이는 파일 설명자 0, 1, 2일 뿐입니다. 이는 사용에 관한 규칙입니다.
마지막 단락이 아닙니다. 터미널 창이 저장되었습니다. 파일 설명자를 삭제해도 파일은 삭제되지 않습니다. 디렉토리 항목만 삭제 되더라도 rm
파일은 삭제되지 않습니다(다른 답변의 참조 계산 참조: 참조하는 항목이 없으면 파일이 삭제됩니다). 따라서 파일에 디렉터리 항목이 없고 어떤 프로세스에서도 열리지 않으면 파일이 삭제됩니다.