2011-09-06 2 views
2

fwrite 또는 fprintf을 호출하거나 파일에 쓰는 다른 함수를 호출하면 내용이 즉시 디스크로 플러시되지 않고 메모리에 버퍼링된다는 것을 알고 있습니다.OS가 파일 버퍼링을 수행하는 방법

첫째로, OS는 어디에서 이러한 버퍼를 관리합니까? 둘째, 파일에 쓰고 나중에 작성한 내용을 읽고 OS가 작성한 시간과 읽은 시간 사이에 내용을 플러시하지 않는다고 가정하면 버퍼에서 읽기를 반환해야한다는 것을 어떻게 알 수 있습니까? ? 이 상황을 어떻게 처리 할 수 ​​있습니까?

내가 알고 싶은 이유는 OS에서 수행 한 것처럼 커널 공간보다는 사용자 공간에 내 자신의 버퍼링 체계를 구현하는 데 관심이 있기 때문입니다. 즉, 파일에 대한 쓰기는 사용자 공간에서 버퍼링되며 실제 쓰기는 특정 지점에서만 발생합니다. Consquently 나는 여전히 버퍼에있는 내용에 대한 읽기가 호출되는 상황을 처리해야합니다. 이 모든 작업을 사용자 공간에서 수행 할 수 있습니까? OS를 할 첫째

답변

4

,이 버퍼를 관리하는 방법과

기능 fwrite 이미 완전히 사용자 공간에 입니다 fprintf 사용 표준 입출력 버퍼. 버퍼는 (아마도) 정적 배열이거나 malloced 메모리 일 수 있습니다. 그것은 그것은, 그래서 변경을 보이지 않는하지 않는 버퍼

에서 읽기를 반환하는 것을 알고 어떻게

. 기본 시스템 호출 (write)이 호출 될 때까지 파일에 실제로 아무 것도 발생하지 않습니다.

은 가능한 사용자 공간에서

아니, 불가능이 모든 작업을 수행하는 것입니다. 좋은 소식은 커널이 이미 버퍼을 가지고 있으므로 write이 실제로 파일에 실제로 쓰여지는 것이 아닙니다. 나중에 연기되고 실행됩니다. 그 동안 누군가가 파일에서 읽으려고하면, 커널은 버퍼에서 그를 섬기기에 충분히 똑똑합니다. TLPI에서

비트 :

디스크 파일 읽기 (작업) 및 쓰기() 시스템이 직접 ini- tiate 디스크 액세스를하지 않는 호출합니다. 그 대신, 커널 버퍼 캐시에있는 사용자 공간 버퍼와 버퍼 사이에 데이터 을 복사하기 만하면됩니다.

커널이 디스크 I/O의 버퍼링을 수행하기 때문에 디스크 파일에서 I/O를 수행 할 때 write() 에서 데이터를 성공적으로 반환한다고해서 데이터가 디스크로 전송되었다고 보장 할 수는 없습니다. 디스크 활동 및 write() 호출을 신속하게 처리하십시오. 나중에 커널은 해당 버퍼를 디스크에 기록 (플러시)합니다.

중간에 다른 프로세스가 파일을 의이 바이트 읽기를 시도, 경우

커널이 자동으로 오히려 파일 (의 오래된 내용)에서보다는 버퍼 캐시의 데이터를 제공합니다.

syncfsync에 대해 알아볼 수 있습니다.

여러 수준의 버퍼링은 일반적으로 좋지 않습니다. stdio 버퍼가 유용한 이유는 수행 된 시스템 호출 수가 최소화되기 때문입니다. 시스템 호출이 더 저렴하면 아무도 stdio 버퍼를 더 이상 사용하지 않습니다.

+0

cnicutar, 고맙습니다. 그러나 저는 제 목적을 위해 stdio 버퍼 개념을 사용하여 사용자 공간에서 쓰기를 캐시 한 다음 나중에 실제 쓰기를 호출 할 수 있다고 생각합니다. 내 경우에는 쓰기를 즉시 수행 할 수 없기 때문입니다. 나는 50ms 정도마다 시스템의 오류를 검사하고 오류가 없다고 확신 할 때에 만 파일에 기록합니다. 필자는 응용 프로그램에서 안정성을 위해 사용하는 라이브러리에 대해 이야기하고 있으므로 모든 경우에 작동해야합니다. 즉, 응용 프로그램과 관련되어서는 안됩니다. – MetallicPriest

+0

@ MetallicPriest 그것은 의미에서 stdio를 재발 명하게 될 것입니다. 일관성을 기대하지 않는 한 (다른 프로세스가 즉시 수정을 보게 됨) 괜찮을 것입니다. – cnicutar

+0

그래서 stdio가 실제로 시스템 호출을하지 않았을 때 사용자 레벨에서 stdio 쓰기 버퍼에 여전히 보관 된 내용을 읽으면 읽음이 반환됩니까? – MetallicPriest

관련 문제