Разница между fflush и fsync
Я думал, что fsync () делает fflush () внутренне, поэтому использование fsync () в потоке в порядке. Но я получаю неожиданный результат при выполнении под сетевым вводом-выводом
мой фрагмент кода:
FILE* fp = fopen(file,"wb");
/* multiple fputs() call like: */
fputs(buf, fp);
...
...
fputs(buf.c_str(), fp);
/* get fd of the FILE pointer */
fd = fileno(fp);
#ifndef WIN32
ret = fsync(fd);
#else
ret = _commit(fd);
fclose(fp);
но, похоже, _commit () не смывает данные (я пробовал в Windows, и данные были записаны в экспортированной файловой системе Linux).
когда я изменил код так:
FILE* fp = fopen(file,"wb");
/* multiple fputs() call like: */
fputs(buf, fp);
...
...
fputs(buf.c_str(), fp);
/* fflush the data */
fflush(fp);
fclose(fp);
на этот раз он сбрасывает данные.
мне интересно, если _commit() делает то же самое, что и fflush(). Какие входы?
5 ответов
fflush()
работает на FILE*
, Он просто сбрасывает внутренние буферы в FILE*
вашего приложения в ОС.
fsync
работает на более низком уровне, он говорит ОС, чтобы очистить свои буферы на физические носители.
OSs сильно кэширует данные, которые вы записываете в файл. Если бы ОС заставляла каждую запись попадать на диск, все было бы очень медленно. fsync
(среди прочего) позволяет контролировать, когда данные должны попасть в водить.
кроме того, fsync/commit работает с файловым дескриптором. Он не знает о FILE*
и не может очистить свои буферы. FILE*
живет в вашем приложении, файловые дескрипторы живут в ядре ОС, как правило.
стандартная функция C fflush()
и системный вызов POSIX fsync()
концептуально чем-то похожи. fflush()
работает на потоках файлов C (FILE
objects), и поэтому является портативным.
fsync()
работать с файловыми дескрипторами POSIX.
В обоих случаях буферизованные данные отправляются в пункт назначения.
в системе POSIX каждый поток файлов C связан файловый дескриптор, и все операции над потоком файлов C будут реализованы путем делегирования, когда это необходимо, to POSIX системные вызовы, которые работают с файловым дескриптором.
можно подумать, что вызов fflush
в системе POSIX вызовет write
любых данных в буфере файлового потока с последующим вызовом fsync()
для файлового дескриптора этого файлового потока. Таким образом, в системе POSIX не было бы необходимости следовать вызову fflush
С fsync(fileno(fp))
. Но так ли это: есть ли призыв к fsync
С fflush
?
нет, называя fflush
на POSIX система не подразумевает, что fsync
будет называться.
стандарт C для fflush
говорит (Курсив мой) это
вызывает любые неписаные данные для [потока], которые будут доставлены в среду хоста будет написано в файле
говоря, что данные на написано, а не то is written подразумевает, что дальнейшая буферизация средой хоста разрешена. Что буферизация "средой хоста" может включать в себя для среды POSIX внутреннюю буферизацию, которая fsync
ает. Таким образом, близкое чтение стандарта C предполагает, что стандарт не требует реализации POSIX для вызова fsync
.
на стандартное описание POSIX fflush
не объявляет, как расширение семантики C, что fsync
называется.
я мог бы сказать, что для простоты:
использовать fsync()
С не потоковыми файлами (целочисленные файловые дескрипторы)
использовать fflush()
с файловыми потоками.
также Вот помощь от человека:
int fflush(FILE *stream); // flush a stream, FILE* type
int fsync(int fd); // synchronize a file's in-core state with storage device
// int type
чтобы принудительно зафиксировать последние изменения на диске, используйте функции sync() или fsync ().
fsync () синхронизирует все данные и метаданные данного файла с постоянным запоминающим устройством. Он должен быть вызван непосредственно перед закрытием соответствующего файла.
sync () будет сохранить все измененные файлы на диск.
Я думаю, что ниже документа из python (https://docs.python.org/2/library/os.html) проясняет это очень хорошо.
os.fsync (fd) принудительно записывает файл с filedescriptor fd на диск. На Unix, это вызывает собственную функцию fsync (); в Windows, MS _commit (функция).
Если вы начинаете с объекта файла Python f, сначала сделайте f.смыв(), а потом сделать ОС.fsync(f.fileno ()), чтобы гарантировать, что все внутренние буферы связанные с ф записано на диск.
доступность: Unix и Windows, начиная с версии 2.2.3.