다음 코드가 있습니다.
FILE *file = fopen("testfile.txt", "r+");
int fdfile = open("testfile.txt", O_RDONLY | O_SYNC);
const char word[] = "writing to a file and read test";
fwrite(word, sizeof(word)-1, 1, file);
fsync(fdfile);
char word1[1024] = {0};
int n = read(fdfile, word1, sizeof(word)-1);
printf("%s\n%d", word1, n);
fclose(file);
실행 직전에 파일에 testfile.txt
내용이 포함되어 있습니다.prev content
일단 이것을 실행하면 나는 얻는다.
prev content
12
최신 콘텐츠여야 하지만 writing to a file and read test
. 나는 그것을 fsync(fdfile)
아무 소용없이 사용했습니다. 나도 시도했지만 sync()
그 fsync(fileno(file))
중 아무것도 작동하지 않았습니다. 쓰기 후에 콘텐츠를 디스크에 플러시해야 하기 때문에 작동해야 하지만 작동하지 않았습니다.
읽기 및 쓰기에 동일한 파일 설명자를 사용하면 이 문제를 완화할 수 있다는 것을 알고 있지만 내 코드에서는 이를 수행할 수 없습니다. 이 문제를 완화하고 콘텐츠를 동기화하려면 어떻게 해야 합니까?
답변1
open()
, read()
및 기타 함수는 write()
Posix에서 정의한 하위 수준 함수입니다. 여기에는 일반적으로 실제 미디어로 플러시하는 데 사용하는 버퍼인 시스템 수준(커널) 버퍼가 포함되며 fsync()
이에 대해 많은 제어권이 없습니다.
fopen()
, fread()
, 기타 기능은 fwrite()
C 언어에서 제공하는 고급 기능입니다. 그들은 포함하고추가의를 사용하여 버퍼를 구성할 수 있습니다 setbuf()
. 이 버퍼는 일반적으로 텍스트 파일( , 및 \n
포함 ) 에 대한 라인 버퍼(라인의 각 끝에서 플러시됨) 이고 바이너리 파일에 대한 블록 버퍼(버퍼가 가득 차면 플러시됨)입니다.stdin
stdout
stderr
물론, 낮은 수준과 높은 수준의 읽기/쓰기 기능에 대한 호출을 혼합하는 것은 권장되지 않습니다. 문제는 사용 중인 상위 수준 버퍼가 플러시되지 않았기 때문에 발생합니다 fwrite()
(플러시하는 데 사용한 하위 수준 버퍼로 플러시 fsync()
).
해결책은 호출 fsync()
하거나 열지 않는 것입니다 O_SYNC
(코드에서 제거할 수 있음).
fflush()
필요한 경우 고급 버퍼를 명시적으로 플러시합니다.- 또는 고급 기능을 버퍼링되지 않은 상태로 만듭니다.
setbuf(fdfile, _IONBF)
후자가 더 쉽지만 버퍼는 효율성을 위한 것이며 버퍼링을 해제하면 상위 수준 호출이 각 fwrite()
호출에서 해당 write()
시스템 호출을 트리거하게 되어 성능에 영향을 미칠 수 있으므로 fflush()
필요하다고 생각할 때 더 주의해야 할 수 있습니다. 이것을하고 있습니다.
답변2
나는 이것을 알아 냈습니다.
FILE*
자체 버퍼가 있으며 발생 하기 fflush()
전에 편집 해야 함sync