Как узнать, когда необходима очистка буфера? - PullRequest
0 голосов
/ 02 октября 2018

Учитывая две функции, которые очищают буферы:

  1. fflush()
  2. sync()

Как я могу узнать, когда нужен звонок одному из них?

Я знаю, что добавление '\n' к printf() очистит буфер вывода, но если строка не содержит такого символа, когда я могу пропустить этот вызов, а когда нет (multiмногопоточные системы?)?

То же самое относится и к sync.У меня есть функция, которая сохраняет файлы в файловой системе (сохранение выполняется через серию системных вызовов), и кажется, что без вызова sync файлы не сохраняются в определенном случае

К сожалению, в настоящее время у меня нет всех подробностей по этому делу [. Что я знаю, так это то, что файлы сохраняются, и сразу после этого происходит отключение питания (не знаю точно, как скоро), ифайлов нет после перезагрузки ].Во всех тестах, которые я запускаю, файлы были сохранены правильно.

Итак, как я могу выяснить, когда система очистит буферы данных / метаданных файла, а когда - нет, и мне нужно явно вызватьsync()?

Цитирующий man (который не указывает, когда необходим явный вызов) :

sync, syncfs - commit buffer cache to disk
sync() causes all buffered modifications to file metadata and data to be written to the underlying file systems.

fflush - flush a stream
For  output  streams,  fflush() forces a write of all user-space buffered data for the given output or update stream via the stream's underlying write function.  For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.  The open status  of the stream is unaffected.

Дополнительный вопрос:

1-й комментарий к этому ответу показывает способ отключения буферизации stdout с помощью setbuf(stdout, NULL);.Есть ли что-то вроде sync (какой буфер используется для этого?)?

1 Ответ

0 голосов
/ 02 октября 2018

sync()

Вам редко требуется вызов sync().Когда вы это сделаете, у вас есть что-то, что важно, должно быть записано на диск как можно скорееОднако sync() вернется, запланировав запись буферов в память ядра, а не после того, как они были записаны, поэтому вы не будете знать, что они действительно были записаны - так что это не совсем надежно.Если вам нужен больший контроль над записью для вашего файла, посмотрите на флаги O_SYNC, O_DSYNC, O_RSYNC для open().Возможно, вам придется использовать fcntl() и fileno() для установки этих флагов, если вы используете файловые потоки, а не файловые дескрипторы.

Два предостережения:

  1. sync() не будет записывать буферы из вашего процесса (или любого другого процесса) в пул буферов ядра;оно совершенно не связано с fflush().
  2. sync() влияет на все данные, записанные всеми процессами в системе - вы можете стать непопулярным, если ваше приложение использует его очень часто;это подрывает хорошую работу, которую ядро ​​выполняет кеширование данных.

fflush()

Функция fflush() гарантирует, что данные были записаны в буфер ядрапулы из буфера вашего приложения (либо для одного файла, либо для всех выходных файлов, если вы используете fflush(0) или fflush(NULL)).Это не влияет напрямую на другие процессы.Опять же, вы используете это, когда вам нужно быть уверенным, что ожидающий вывод был отправлен ядру для последующей передачи.Единственное место, где вы можете его использовать, - это перед операцией ввода, где вы хотите, чтобы появилось приглашение, даже если в конце не было новой строки.В противном случае вы не часто используете его, но вы можете использовать его всякий раз, когда хотите убедиться, что данные были отправлены в ядро ​​для записи.Если вы отлаживаете и ваша программа вылетает, разбрасывание операторов fflush() может гарантировать, что ожидающий вывод будет записан до сбоя.Это может помочь более точно выявить, в чем проблема (как и при использовании отладчика).

Обратите внимание, что настройка небуферизованного вывода (setbuf(stdout, NULL) или setvbuf(stdout, NULL, _IONBF, 0)) означает, что весь вывод происходит «немедленно».Это не обязательно хорошо для производительности.Вы используете его иногда, но довольно редко.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...