Как ОС выполняет буферизацию для файла - PullRequest
2 голосов
/ 06 сентября 2011

Я знаю, что когда вы вызываете fwrite или fprintf или, скорее, любую другую функцию, которая записывает в файл, содержимое не сразу записывается на диск, а помещается в буфер.

Во-первых, где ОС управляет этими буферами и как. Во-вторых, если вы выполняете запись в файл, а затем читаете содержимое, которое вы написали, и предполагаете, что ОС не сбрасывает содержимое между временем, которое вы записали и прочитали, то откуда она знает, что должна вернуть чтение из буфера ? Как это справиться с этой ситуацией.

Причина, по которой я хочу это знать, заключается в том, что я заинтересован в реализации моей собственной схемы буферизации в пространстве пользователя, а не в пространстве ядра, как это делает ОС. То есть запись в файл будет буферизироваться в пространстве пользователя, а фактическая запись будет происходить только в определенной точке. Следовательно, мне также нужно обрабатывать ситуации, когда чтение вызывается для содержимого, которое все еще находится в буфере. Возможно ли сделать все это в пространстве пользователя.

1 Ответ

4 голосов
/ 06 сентября 2011

Во-первых, где ОС управляет этими буферами и как

Функции fwrite и fprintf используют буферы stdio, которые уже полностью находятся в пользовательском пространстве . Буферы - это (скорее всего) статические массивы или, возможно, неправильная память.

откуда он знает, что должен вернуть чтение из буфера

Нет, поэтому изменения не видны . На самом деле с файлом ничего не происходит до тех пор, пока не будет вызван базовый системный вызов (write) (и даже тогда - читать дальше).

Можно ли сделать все это в пространстве пользователя

Нет, это невозможно. Хорошая новость заключается в том, что ядро ​​уже имеет буферы , поэтому каждый write, который вы делаете, не переводится в фактическую запись в файл. Это отложено и выполнено позже. Если тем временем кто-то пытается прочитать из файла, ядро ​​достаточно умен, чтобы обслуживать его из буфера.

Биты из TLPI:

При работе с дисковыми файлами системные вызовы read () и write () непосредственно не инициируйте доступ к диску. Вместо этого они просто копируют данные между буфером пространства пользователя и буфером в буферном кеше ядра.

При выполнении операций ввода-вывода для файла на диске успешное завершение операции write () не гарантирует, что данные были перенесены на диск, потому что ядро выполняет буферизацию дискового ввода-вывода, чтобы уменьшить диск активность и ускоренная запись () звонков. В более поздний момент ядро ​​записывает (сбрасывает) свой буфер в диск.

Если тем временем другой процесс пытается прочитать эти байты файла, то ядро ​​автоматически передает данные из буферный кеш , а не из (устаревшего содержимого) файла.

Так что вы можете узнать о sync и fsync.

Несколько уровней буферизации обычно плохие. Причина, по которой буферы stdio полезны, заключается в том, что они сводят к минимуму количество выполняемых системных вызовов. Если бы системный вызов был дешевле, никто бы больше не использовал буферы stdio.

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