2015-11-10 4 views
0

Я недавно изучал файловую систему в Linux. Я узнал, что когда мы вызываем fopen(), вызов библиотеки вызывает malloc(), чтобы выделить пространство для структуры FILE, и внутри этой структуры FILE будет существовать буфер для I/0. Но позже я обнаружил, что системный вызов записи фактически записывает данные в буфер ядра. Так в чем разница между этими двумя буферами?Пользовательский буфер пространства и буфер ядра

+0

Не против того, что вам нужно иметь книгу, чтобы прочитать первый. –

+0

У меня есть книга, это расширенное программирование UNIX. Просто хочу, чтобы все получилось. –

ответ

1

Структура FILE содержит meta данные об открытом файле (режим, положение потока и т. Д.). Он является частью интерфейса стандартного ввода-вывода C. Буфер, выделенный как часть FILE, принимает только ограниченный объем данных (например, когда буфера буфера). Он освобождается от fclose(). Вы даже можете предоставить свой собственный буфер stdio для пользовательского пространства с setvbuf().

Буфер ядра принимает содержимое , написанное write(), всякий раз, когда поток очищается или соответствующий дескриптор файла закрыт.

+0

Означает ли это, что если поток буферизуется, данные сначала записываются в буфер пространства пользователя, а затем в буфер пространства ядра? Но что, если поток не буферизуется, например, stderr, означает ли это, что вывод идет прямо к сообщению об ошибке и даже не сохраняется в кеше ядра? –

+0

@lplouis Да, если поток буферизирован, он сначала переходит в буфер 'FILE'. В этом весь смысл: избегать ** дорогостоящих ** системных вызовов только для нескольких байтов. Если он не буферизирован, любая операция переходит непосредственно к read() или write(). Последнее, что вы обычно хотите для диагностических сообщений: вы хотите получить информацию, как только что-то пойдет не так. – Jens

0

Структура FILE содержит информацию об открывшемся файле. this defines the FILE struct members. Но на уровне ядра к файлу обратился inode, buffer cache.

Данные получают чтение/запись на диск из пользовательского пространства через буферный кеш с использованием метода copy_to_user и copy_from_user.

1

Вы должны понимать две вещи: fwrite() - стандартная библиотека, работающая по структуре FILE, но write() - системный вызов. Держу пари, fwrite() использует write() внутренне. Ничто не удерживает fwrite() от предоставления пользовательского пространства IO-буферизации, пока оно не будет готово передать ваши данные в системный вызов write().

write() syscall в свою очередь направляется прямо к ядру и говорит: «Привет, я имею этот буфер пространства пользователя здесь. Вы напишете это для хранения?». И здесь дело до ядра, что делать дальше: он либо перейдет непосредственно к хранилищу для записи данных, либо, скорее всего, скопирует данные в буфер ядра, пока не решит, что пришло время изменить данные хранилища.

Возвращаясь к вашему вопросу. Любая буферизация выполняется для накопления данных, чтобы отложить переход к более дорогостоящим операциям: стандартная библиотека может рассматривать вызов syscall на каждом -байте дорого, ядро ​​считает, что переход на жесткий диск на каждый syscall дорогостоящий и так далее.

Вы можете прочитать это, чтобы увидеть, как далеко буферизация идет https://fgiesen.wordpress.com/2015/10/25/reading-and-writing-are-less-symmetric-than-you-probably-think/

+0

Итак, функция библиотеки имеет свой собственный буфер или буфер находится в структуре FILE? –

+0

Это, кажется, в структуре 'FILE'.Посмотрите, библиотека буферизует IO для каждого файла. Чтобы выполнить свою работу по каждому файлу, он придает приложению некоторый непрозрачный дескриптор 'FILE *', так что, когда вы переходите к подпрограмме библиотеки, вы передаете этот дескриптор. Этот дескриптор рассказывает все о рутине, которую последний должен знать, чтобы сделать это работа (включая буферизацию). –

Смежные вопросы