파이썬의 file.flush ()는 정확히 무엇을합니까?


137

File Objects 에 대한 Python 설명서 에서 이것을 발견했습니다 .

flush ()는 반드시 파일의 데이터를 디스크에 쓸 필요는 없습니다. flush () 다음에 os.fsync ()를 사용하여이 동작을 확인하십시오.

그래서 내 질문은 : 파이썬이 정확히 무엇을 flush하고 있습니까? 디스크에 데이터를 쓰도록 강요했지만 지금은 그렇지 않습니다. 왜?

답변:


220

일반적으로 두 가지 레벨의 버퍼링이 관련됩니다.

  1. 내부 버퍼
  2. 운영 체제 버퍼

내부 버퍼는 프로그래밍중인 런타임 / 라이브러리 / 언어에 의해 생성 된 버퍼이며 모든 쓰기에 대한 시스템 호출을 피함으로써 작업 속도를 향상시킵니다. 대신 파일 객체에 쓸 때 해당 버퍼에 쓴 다음 버퍼가 채워질 때마다 시스템 호출을 사용하여 데이터가 실제 파일에 기록됩니다.

그러나 운영 체제 버퍼로 인해 데이터가 디스크에 기록 되는 것은 아닙니다 . 데이터가 런타임에 의해 유지 관리되는 버퍼에서 운영 체제가 유지 관리하는 버퍼로 복사된다는 의미 일 수도 있습니다.

무언가를 쓰면 버퍼에서 끝나고 (머신) 전원이 꺼지면 머신이 꺼질 때 해당 데이터가 디스크에 있지 않습니다.

그와 함께 그래서, 도움을 위해 당신이 가지고있는 flushfsync 위해 각각의 객체에 메소드가 있습니다.

첫 번째 flush는 프로그램 버퍼에 남아있는 데이터를 실제 파일에 기록합니다. 일반적으로 이는 데이터가 프로그램 버퍼에서 운영 체제 버퍼로 복사됨을 의미합니다.

특히 이것은 다른 프로세스가 동일한 파일을 읽기 위해 열려있는 경우 방금 파일로 플러시 한 데이터에 액세스 할 수 있다는 것입니다. 그러나 반드시 "영구적으로"디스크에 저장되었다는 의미는 아닙니다.

그렇게하려면 os.fsync 모든 운영 체제 버퍼가 저장 장치와 동기화되도록 메소드 즉,이 메소드는 운영 체제 버퍼에서 디스크로 데이터를 복사합니다.

일반적으로 두 방법 중 하나를 신경 쓸 필요는 없지만 실제로 디스크에서 끝나는 것에 대한 편집증이 좋은 시나리오 인 경우 지시에 따라 두 호출을 모두 수행해야합니다.


2018 년 부록.

캐시 메커니즘이있는 디스크는 이제 2013 년보다 훨씬 일반적이므로 이제 더 많은 수준의 캐싱 및 버퍼가 필요합니다. 나는 가정 이 버퍼뿐만 아니라 동기화 / 플러시 호출에 의해 처리됩니다,하지만 난 정말 모르겠어요.


10
with file('blah') as fd: #dostuff구문을 사용할 때 파일 설명자를 닫을 수 있음을 알고 있습니다. 또한 플러시 또는 동기화됩니까?
Marcin

3
@Marcin : 플러시되지만 동기화되지 않습니다.
Alex I

8
fsync원자성에 필요합니다. 파일을 닫고 다시 열고 fsync중간에 파일이없는 컨텐츠를 찾을 수 없습니다 . 종종 작동하지만 ext4 및 기본 마운트 옵션이있는 Linux에서는 그렇지 않습니다. 또한 fsync1 : 랩톱 모드에서 fsync를 비활성화 할 수 있고 2 : 하드 디스크 내부 버퍼링이 플러시를 지시하지 않을 수 있기 때문에 플래터에서 다리미를 실제로 자석으로 튕기는 것이 보장되지 않습니다.
v.oddou

1
파일이 다른 프로세스에 의해 작성된 경우 모든 파일에 대해 운영 체제 버퍼를 플러시하는 방법이 있습니까?
Nacht

1
fsync는 비교적 비쌉니다. 일반적으로 디스크 액세스를 위해 100 % ACID 준수 및 내구성이 필요한 미션 크리티컬 한 소프트웨어를 작성하지 않고 있으며,이를 아는 경우 고통스럽게 알고 있으며 이러한 보증을 받기 위해 취할 수있는 단계를 알고 있어야합니다. . fsync를 호출하면 디스크에 데이터를 기록하기 위해 실제 디스크 액세스가 발생할 때까지 대기하는 반면, 플러시 및 닫기는 데이터가 캐시 메모리로 이동 될 때까지만 대기합니다. 속도 차이는 아마도 몇 자릿수 일 것입니다.
Lasse V. Karlsen

10

운영 체제가 그렇지 않을 수 있기 때문입니다. 플러시 작업은 파일 데이터를 RAM의 파일 캐시에 저장하며, 실제로 디스크에서 파일을 전송하는 것은 OS의 작업입니다.


6
맞습니다. 그러나 actually여기에 상대적입니다. 대상 장치가 쓰기 캐싱을 활성화 한 경우 데이터가 os.fsync()반환 될 때 실제 플래터 / 칩에 도달하지 않았을 수 있습니다 .
프레데릭 하 미디

7

내부 버퍼를 플러시하여 OS가 버퍼를 파일에 씁니다. [1] Python은 달리 구성하지 않는 한 OS의 기본 버퍼링을 사용합니다.

그러나 때때로 OS는 여전히 협력하지 않기로 선택합니다. 특히 Windows / NTFS의 쓰기 지연과 같은 멋진 기능이 있습니다. 기본적으로 내부 버퍼는 플러시되지만 OS 버퍼는 계속 유지합니다. 따라서 OS에 디스크에 쓰도록 지시해야합니다 os.fsync().

[1] http://docs.python.org/library/stdtypes.html


0

flush ()는 기본적으로 RAM 버퍼를 정리합니다. 실제로 나중에 나중에 계속 쓸 수는 있지만 파일에 대한 가장 안전하고 안전한 쓰기 기능으로 생각해서는 안됩니다. 더 많은 데이터를 얻기 위해 RAM을 비우는 것입니다. 데이터가 파일에 안전하게 기록되도록하려면 close ()를 대신 사용하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.