두 개의 파일 설명자를 동일한 파일(읽기용과 쓰기용)로 동기화하는 방법

두 개의 파일 설명자를 동일한 파일(읽기용과 쓰기용)로 동기화하는 방법

다음 코드가 있습니다.

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포함 ) 에 대한 라인 버퍼(라인의 각 끝에서 플러시됨) 이고 바이너리 파일에 대한 블록 버퍼(버퍼가 가득 차면 플러시됨)입니다.stdinstdoutstderr

물론, 낮은 수준과 높은 수준의 읽기/쓰기 기능에 대한 호출을 혼합하는 것은 권장되지 않습니다. 문제는 사용 중인 상위 수준 버퍼가 플러시되지 않았기 때문에 발생합니다 fwrite()(플러시하는 데 사용한 하위 수준 버퍼로 플러시 fsync()).

해결책은 호출 fsync()하거나 열지 않는 것입니다 O_SYNC(코드에서 제거할 수 있음).

  • fflush()필요한 경우 고급 버퍼를 명시적으로 플러시합니다.
  • 또는 고급 기능을 버퍼링되지 않은 상태로 만듭니다.setbuf(fdfile, _IONBF)

후자가 더 쉽지만 버퍼는 효율성을 위한 것이며 버퍼링을 해제하면 상위 수준 호출이 각 fwrite()호출에서 해당 write()시스템 호출을 트리거하게 되어 성능에 영향을 미칠 수 있으므로 fflush()필요하다고 생각할 때 더 주의해야 할 수 있습니다. 이것을하고 있습니다.

답변2

나는 이것을 알아 냈습니다.

FILE*자체 버퍼가 있으며 발생 하기 fflush()전에 편집 해야 함sync

관련 정보