나의 예는 마인크래프트이다. Linux에서 Bukkit을 실행할 때 /plugins 폴더에서 .jar 파일을 삭제하거나 업데이트한 다음 간단히 "reload" 명령을 실행할 수 있습니다.
Windows에서는 .jar 파일을 삭제하거나 교체하려고 하면 해당 파일이 현재 사용 중이라는 메시지가 표시되므로 전체 서버 프로세스를 종료해야 합니다.
나에게는 좋은 일이지만 왜 이런 일이 발생합니까? 여기서 Linux는 무엇을 다르게 하고 있습니까?
답변1
Linux가 파일을 삭제하는 방식은 Windows와 완전히 다릅니다. 먼저 *unix 기본 파일 시스템에서 파일이 관리되는 방법에 대한 간략한 설명입니다.
파일은 이라는 다중 레벨 구조로 디스크에 저장됩니다 i-node
. 각 i-노드는 단일 파일 시스템에서 고유한 번호를 갖습니다. i-노드 구조는 파일 크기, 파일에 할당된 데이터 블록 등과 같은 파일에 대한 다양한 정보를 보유하지만 이 질문에 답하기 위해 가장 중요한 데이터 요소는 파일에 대한 기록을 보유하는 파일입니다 link counter
. directories
각 레코드에는 참조하는 inode 번호, 파일 이름의 길이 및 파일 이름 자체가 있습니다. 이 체계를 사용하면 "포인터", 즉 다른 이름을 가진 다른 위치에 있는 동일한 파일에 대한 "링크"를 가질 수 있습니다. i-노드의 링크 카운터는 실제로 해당 i-노드를 참조하는 링크 수를 저장합니다.
프로세스에서 파일을 열면 어떻게 되나요? 먼저 open()
함수는 파일 레코드를 검색합니다. 그런 다음 해당 i-노드에 대한 메모리에 i-노드 구조가 이미 존재하는지 확인합니다. 일부 응용 프로그램에서 이 파일이 열려 있는 경우 이런 일이 발생할 수 있습니다. 그렇지 않으면 시스템은 새로운 메모리 i-노드 구조를 초기화합니다. 그런 다음 시스템은 메모리에 있는 inode 구조의 열린 카운터를 증가시키고 해당 파일 설명자를 애플리케이션에 반환합니다.
파일 삭제를 위한 Linux 라이브러리 호출을 이라고 합니다 unlink
. 이 함수는 디렉토리에서 파일 레코드를 제거하고 i-노드의 링크 카운터를 감소시킵니다. 시스템이 inode 구조가 메모리에 존재하고 해당 오픈 카운터가 0이 아님을 발견하면 이 호출은 애플리케이션에 제어를 반환합니다. 그렇지 않으면 링크 카운터가 0에 도달했는지 확인하고, 그렇다면 시스템은 inode와 inode 자체에 할당된 모든 블록을 해제하고 이를 애플리케이션에 반환합니다.
응용 프로그램이 파일을 닫으면 어떻게 되나요? 이 함수는 close()
오픈 카운터를 감소시키고 그 값을 확인합니다. 값이 0이 아닌 경우 함수는 애플리케이션으로 반환됩니다. 그렇지 않으면 i-노드 링크 카운터가 0인지 확인합니다. 0이면 파일의 모든 블록과 inode가 애플리케이션으로 반환되기 전에 해제됩니다.
이 메커니즘을 사용하면 파일이 열려 있는 동안 "삭제"할 수 있습니다. 동시에 파일을 연 응용 프로그램은 계속해서 파일의 데이터에 액세스할 수 있습니다. 따라서 귀하의 예에서 JRE는 여전히 파일 버전을 열어두고 디스크에는 또 다른 최신 버전이 있습니다.
또한 이 기능을 사용하면 정상적인 작동을 중단하지 않고 시스템에서 glibc(libc)(모든 응용 프로그램의 핵심 라이브러리)를 업데이트할 수 있습니다.
윈도우
20년 전만 해도 우리는 FAT 외에 DOS의 다른 파일 시스템을 알지 못했습니다. 이러한 파일 시스템은 구조와 관리 원칙이 다릅니다. 이러한 원칙은 파일이 열려 있는 동안 파일을 삭제하는 것을 허용하지 않으므로 DOS와 최근에는 Windows는 열린 파일에 대한 삭제 요청을 거부해야 합니다. NTFS는 *nix 파일 시스템과 동일한 동작을 허용할 수 있지만 Microsoft는 파일 삭제의 관례적인 동작을 유지하기로 결정했습니다.
이것이 답입니다. 짧지는 않지만 이제 아이디어가 생겼습니다.
편집하다Win32
: 혼란의 원인에 대해 잘 읽었습니다.https://web.archive.org/web/20190218083407/https://blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p=38993
@존 감사합니다