Во-первых, где ОС управляет этими буферами и как
Функции fwrite
и fprintf
используют буферы stdio, которые уже полностью находятся в пользовательском пространстве . Буферы - это (скорее всего) статические массивы или, возможно, неправильная память.
откуда он знает, что должен вернуть чтение из буфера
Нет, поэтому изменения не видны . На самом деле с файлом ничего не происходит до тех пор, пока не будет вызван базовый системный вызов (write
) (и даже тогда - читать дальше).
Можно ли сделать все это в пространстве пользователя
Нет, это невозможно. Хорошая новость заключается в том, что ядро уже имеет буферы , поэтому каждый write
, который вы делаете, не переводится в фактическую запись в файл. Это отложено и выполнено позже. Если тем временем кто-то пытается прочитать из файла, ядро достаточно умен, чтобы обслуживать его из буфера.
Биты из TLPI:
При работе с дисковыми файлами системные вызовы read () и write ()
непосредственно не инициируйте доступ к диску. Вместо этого они просто копируют данные
между буфером пространства пользователя и буфером в буферном кеше ядра.
При выполнении операций ввода-вывода для файла на диске успешное завершение операции write ()
не гарантирует, что данные были перенесены на диск, потому что
ядро выполняет буферизацию дискового ввода-вывода, чтобы уменьшить диск
активность и ускоренная запись () звонков.
В более поздний момент ядро записывает (сбрасывает) свой буфер в
диск.
Если тем временем другой процесс пытается прочитать эти байты
файла, то ядро автоматически передает данные из
буферный кеш , а не из (устаревшего содержимого) файла.
Так что вы можете узнать о sync
и fsync
.
Несколько уровней буферизации обычно плохие. Причина, по которой буферы stdio
полезны, заключается в том, что они сводят к минимуму количество выполняемых системных вызовов. Если бы системный вызов был дешевле, никто бы больше не использовал буферы stdio.