В левой части схемы на рис. 13.1 показаны вызовы, которые могут использоваться в любое время для явного принудительного сброса любого из буферов. В правой части показаны вызовы, которые могут применяться для автоматического выполнения сброса либо за счет выключения буферизации в библиотеке stdio, либо включением для системных вызовов файлового вывода синхронного режима выполнения, чтобы при каждом вызове write() происходил немедленный сброс на диск.
Рис. 13.1.
Системный вызов posix_fadvise() позволяет процессу информировать ядро о предпочитаемой им схеме обращения к данным файла.
Ядро может (но не обязано) использовать информацию, предоставляемую системным вызовом posix_fadvise() для оптимизации задействования им буферной кэш-памяти, повышая тем самым производительность ввода-вывода для процесса и для системы в целом. На семантику программы вызов posix_fadvise() не влияет.
#define _XOPEN_SOURCE 600
#include
int posix_fadvise(int
Возвращает при успешном завершении 0 или положительный номер ошибки при ее возникновении
Аргумент fd является дескриптором файла, идентифицирующим тот файл, о схеме обращения к которому нужно проинформировать ядро. Аргументы offset и len идентифицируют область файла, к которой относится уведомление: offset указывает на начальное смещение области, а len — на ее размер в байтах. Присвоение для len значения 0 говорит о том, что имеются в виду все байты, начиная с offset и заканчивая концом файла. (В версиях ядра до 2.6.6 значение 0 для len интерпретировалось буквально, как 0 байт.)
Аргумент advice показывает предполагаемый характер обращения процесса к файлу. Он определяется с одним из следующих значений.
• POSIX_FADV_NORMAL — у процесса нет особого уведомления, касающегося схем обращения. Это поведение по умолчанию, если для файла не дается никаких уведомлений. В Linux эта операция устанавливает для окна упреждающего считывания данных из файла его исходный размер (128 Кбайт).
• POSIX_FADV_SEQUENTIAL — процесс предполагает последовательное считывание данных от меньших смещений к бóльшим. В Linux эта операция устанавливает для окна упреждающего считывания данных из файла его удвоенное исходное значение.
• POSIX_FADV_RANDOM — процесс предполагает обращение к данным в произвольном порядке. В Linux этот вариант отключает упреждающее считывание данных из файла.
• POSIX_FADV_WILLNEED — процесс предполагает обращение к указанной области файла в ближайшее время. Ядро выполняет упреждающее считывание данных для заполнения буферной кэш-памяти данными файла в диапазоне, заданном аргументами offset и len. Последующие вызовы read() в отношении файла не блокируют дисковый ввод-вывод, а просто извлекают данные из буферной кэш-памяти. Ядро не дает никаких гарантий насчет продолжительности нахождения извлекаемых из файла данных в буферной кэш-памяти. Если при работе другого процесса или ядра возникнет особая потребность в памяти, то страница в конечном итоге будет повторно использована. Иными словами, если память остро востребована, нам нужно гарантировать небольшой разрыв по времени между вызовом posix_fadvise() и последующим вызовом (или вызовами) read(). (Функциональные возможности, эквивалентные операции POSIX_FADV_WILLNEED, предоставляет характерный для Linux системный вызов readahead().)
• POSIX_FADV_DONTNEED — процесс не предполагает в ближайшем будущем обращений к указанной области файла. Тем самым ядро уведомляется, что оно может высвободить соответствующие страницы кэш-памяти (если таковые имеются). В Linux эта операция выполняется в два этапа. Сначала, если очередь записи на базовом устройстве не переполнена серией запросов, ядро сбрасывает любые измененные страницы кэш-памяти в указанной области. Затем ядро предпринимает попытку высвободить все страницы кэш-памяти из указанной области. Для измененных страниц в данной области второй этап завершится успешно, только если они были записаны на базовое устройство в ходе первого этапа, то есть очередь записи на устройстве не переполнена. Так как приложение не может проверить состояние очереди на устройстве, гарантировать освобождение страниц кэша можно, вызвав fsync() или fdatasync() в отношении дескриптора fd перед применением POSIX_FADV_DONTNEED.
• POSIX_FADV_NOREUSE — процесс предполагает однократное обращение к данным в указанной области файла, без ее повторного использования. Тем самым ядро уведомляется о том, что оно может высвободить страницы после однократного обращения к ним. В Linux эта операция в настоящее время остается без внимания.
Спецификация posix_fadvise() появилась только в SUSv3, и этот интерфейс поддерживается не всеми реализациями UNIX. В Linux вызов posix_fadvise() предоставляется, начиная с версии ядра 2.6.