일부 Unices에는 "새 버전"이 나올 때까지 커널이 이전 버전(다른 프로세스가 읽기 위해 액세스할 수 있도록)을 사용하도록 요구하는 플래그와 함께 쓰기 위해 기존 파일을 여는 방법이 있었다는 내용을 어딘가에서 읽은 기억이 납니다. 버전이 완전히 작성되었으며(fd가 닫혔음) 이 시점부터 파일이 새 버전으로 나타납니다.
즉, 다른 프로세스에서는 이전 버전이나 새 버전을 볼 수 있지만 불완전하게 작성된 버전은 볼 수 없습니다.
지식이 있는 사람이 나에게 몇 가지 지침을 줄 수 있습니까?
답변1
설명하는 내용은 오버레이 파일의 기본 이름 바꾸기와 똑같습니다.
파일 이름을 바꾸거나 다른 파일 위에 파일을 이동하면 이전 파일의 연결이 해제됩니다. 이는 파일이 여전히 존재하지만 더 이상 파일 시스템 트리에 위치하지 않음을 의미합니다. 따라서 이전 응용 프로그램이 파일을 열어두는 한 계속해서 파일에 액세스할 수 있습니다. 모든 응용 프로그램이 기존 파일을 닫으면 해당 파일은 사실상 디스크에서 할당 해제됩니다.
시스템 rename
호출은 원자성 작업입니다. 따라서 이렇게 하려면 다른 이름으로 새 파일을 만든 다음 rename
임시 파일의 이름을 바꾸려는 파일로 변경을 호출해야 합니다. 작업은 원자적이므로 파일이 손실될 가능성이 전혀 없습니다. 이전 파일에서 새 파일로 즉시 이동됩니다.
그러나 임시 파일과 교체되는 파일은 동일한 마운트 지점에 있어야 합니다.
답변2
~처럼패트릭이 썼다, 일반적인 접근 방식은 새 버전을 별도의 파일에 쓰고 완료되면 새 버전의 이름을 이전 파일 이름으로 바꾸고 자동으로 덮어쓰는 것입니다. 두 번째 작업이라고 합니다.재정의 이름 바꾸기.
이제 일부 참고자료는 다음과 같습니다.
ISO C 요구사항은
rename
원자적입니다.오픈 그룹 기본 사양에서:링크 이름이 있는 경우새로운인수가 존재하므로 제거해야 합니다.오래된다음으로 이름 바꾸기 새로운. 이 예에서 이름이 지정된 링크는새로운이름 바꾸기 작업 전반에 걸쳐 다른 프로세스에 표시되고 참조되어야 합니다.새로운또는오래된수술 시작 전.
이전 버전의 Mac OS X에는 원자 이름 변경 기능이 없습니다. 이 문제는 Lion에서 해결된 것으로 알려졌습니다.
Btrfs는 분명히 의도적으로 표준을 위반합니다.원자 이름 변경은 보장되지 않습니다., 성능상의 이유로. 하지만,이름 바꾸기 재정의는 여전히 원자적입니다., 이것이 이 목적을 위해 필요한 전부입니다.
답변3
이게 생각나네새로 고칠 때 할당됨. 파일 시스템이 이 기능을 사용하면 데이터를 디스크에 직접 쓰는 대신 디스크의 여유 공간 카운터에서 쓸 데이터의 크기를 빼고 동기화 시스템이 수행될 때까지 데이터를 메모리에 보관합니다. 호출 또는 커널이 결정합니다. 더티 버퍼를 플러시합니다.
이 경우 파일이 한 프로세스에 의해 수정되고 다른 프로세스에 의해 열리면 후자의 프로세스는 수정되지 않은 파일(또는 원하는 경우 "오래된") 파일 버전입니다.
물론, 위의 내용은 이론적이며 다양한 요인에 따라 달라집니다. 이는 약간 예측할 수 없습니다. 커널이 언제 더티 페이지를 플러시할지 모르기 때문입니다. 예를 들어 Linux("Linux 커널 이해"의 섹션 15.3을 읽을 수도 있습니다.), 더티 페이지는 다음 조건에서 디스크에 기록됩니다.
페이지 캐시가 너무 가득 차서 더 많은 페이지가 필요하거나 더티 페이지 수가 너무 많아졌습니다.
페이지가 더러워진 채로 너무 많은 시간이 지났습니다.
프로세스는 블록 장치 또는 특정 파일에 대해 보류 중인 모든 변경 사항을 플러시하도록 요청합니다. 이는 sync(), fsync() 또는 fdatasync() 시스템 호출을 호출하여 수행됩니다.
이 기능은 HFS+, XFS, Reiser4, ZFS, Btrfs 및 ext4 파일 시스템에서 구현된 것으로 알려져 있습니다.