필자는 일부 Unices에서 기존 파일을 여는 방법과 커널이 이전 버전 (읽기 위해 액세스하는 다른 프로세스의 경우)을 사용하도록 요청하는 플래그와 함께 "새 파일을 읽을 때까지" "버전이 완전히 작성되었습니다 (fd 닫힘).이 시점에서 파일이 새 버전으로 나타납니다.
다시 말해서, 다른 프로세스는 이전 버전이나 새 버전을 보았으며, 불완전하게 작성된 버전은 결코 없었습니다.
지식이있는 사람이 나를 참조 할 수 있습니까?
필자는 일부 Unices에서 기존 파일을 여는 방법과 커널이 이전 버전 (읽기 위해 액세스하는 다른 프로세스의 경우)을 사용하도록 요청하는 플래그와 함께 "새 파일을 읽을 때까지" "버전이 완전히 작성되었습니다 (fd 닫힘).이 시점에서 파일이 새 버전으로 나타납니다.
다시 말해서, 다른 프로세스는 이전 버전이나 새 버전을 보았으며, 불완전하게 작성된 버전은 결코 없었습니다.
지식이있는 사람이 나를 참조 할 수 있습니까?
답변:
당신이 묘사하는 것은 파일을 덮어 쓰는 기본 이름 바꾸기와 정확히 같습니다.
한 파일을 다른 파일의 이름으로 바꾸거나 이동하면 이전 파일이 연결 해제됩니다. 파일이 여전히 존재하지만 더 이상 파일 시스템 트리에 없다는 것을 의미합니다. 따라서 오래된 응용 프로그램은 파일을 열어 두는 한 계속 파일에 액세스 할 수 있습니다. 모든 응용 프로그램이 이전 파일을 닫으면 디스크에서 실제로 할당 해제됩니다.
rename
시스템 호출은 원자 동작이다. 이렇게하려면 다른 이름으로 새 파일을 만든 다음 호출 rename
하여 임시 파일의 이름을 바꾸려는 파일로 바꾸십시오. 작업이 원 자성이므로 파일이 누락 된 기간은 전혀 없습니다. 오래된 파일에서 새 파일로 즉시 이동합니다.
임시 파일과 교체되는 파일은 동일한 마운트 지점에 있어야합니다.
rename
스왑 작업 을 수행하려면 프로그램을 특별히 작성해야한다고 말하고 있습니다 . 당신이 말하는 것과 같은 'OS 기능'이 존재하더라도, 그것을 활용하기 위해 프로그램을 작성해야 할 것입니다. 차이점이 뭐야?
open
syscall에 (지원되지 않는) 플래그를 전달 하거나 직접 설명하는 것을 수행해야하는 경우 차이가 있습니다.
같이 Patrick이 쓰는 일반적인 방법은 새 버전을 별도의 파일에 쓰고 새 버전의 이름을 이전 파일 이름으로 바꾸면 원자 적으로 덮어 씁니다. 이 두 번째 작업을 덮어 쓰기 별명 이라고 합니다.
ISO C는 rename
원자 적이어야합니다. 공개 그룹 기본 사양에서 :
새로운 인수에 의해 명명 된 링크 가 존재 하면, 그 링크 는 제거되고 오래된 이름은 new 로 바뀝니다 . 이 경우 이름이 new 인 링크 는 이름 바꾸기 작업 전체에서 다른 프로세스에 계속 표시되며 작업이 시작되기 전에 new 또는 old에서 참조한 파일을 참조 해야합니다.
이전 버전의 Mac OS X에는 원자 이름이 바뀌지 않았습니다. 이것은 사자에서 수정 된 것으로 알려져 있습니다.
Btrfs 는 성능상의 이유로 원자 이름 변경을 보장하지 않음 으로써 의도적으로 표준을 위반합니다 . 그러나 이름을 바꾸어 덮어 쓰기는 여전히 atomic이므로이 목적에 필요한 전부입니다.
man 3p rename
그것이 rename
실제로 원자 적이라고 말하면 , 그것은 모든 Linux 파일 시스템을위한 것이라고 생각합니다. 그리고 내가 연결 한 첫 번째 기사를 읽을 때 Btrfs 이름 바꾸기 작업은 원자 적이라고 생각합니다.
이것은 나에게 Allocate On Flush를 상기시킨다 . 파일 시스템이 데이터를 디스크에 직접 쓰는 대신이 기능을 사용하면 디스크의 여유 공간 카운터에서 쓸 데이터의 크기를 빼고 동기화 시스템 호출이 수행되거나 커널이 결정할 때까지 데이터를 메모리에 보유합니다 더티 버퍼를 플러시합니다.
이 경우 파일이 한 프로세스에서 수정되고 다른 프로세스에서 열리면 후자의 프로세스는 파일의 수정되지 않은 ( 또는 원하는 경우 "오래된" ) 버전을 "인식" 합니다.
물론 위의 내용은 이론적이며 다양한 요인에 달려 있으며, 커널이 언제 더티 페이지를 플러시하는지 정확히 알지 못하기 때문에 예측할 수없는 부분이 있습니다. 예를 들어 Linux의 경우 ( Linux 커널 이해의 15.3 섹션에서도 읽을 수 있음 ) 다음과 같은 조건에서 더티 페이지가 디스크에 기록됩니다.
페이지 캐시가 가득 차서 더 많은 페이지가 필요하거나 더티 페이지 수가 너무 많아집니다.
페이지가 더러워진 후 너무 많은 시간이 경과했습니다.
프로세스는 블록 장치 또는 특정 파일의 보류중인 모든 변경 사항을 플러시하도록 요청합니다. sync (), fsync () 또는 fdatasync () 시스템 호출을 호출하여이를 수행합니다.
이 기능은 HFS +, XFS, Reiser4, ZFS, Btrfs 및 ext4 파일 시스템에서 구현되는 것으로 알려져 있습니다.