Буферизованный против небуферизованного ввода-вывода
я узнал, что по умолчанию ввод-вывод в программах буферизуется, т. е. они подаются из временного хранилища в запрашивающую программу.
Я понимаю, что буферизация повышает производительность ввода-вывода (возможно, за счет сокращения системных вызовов). Я видел примеры отключения буферизации, например setvbuf В C. В чем разница между двумя режимами и когда следует использовать один над другим?
2 ответов:
вы хотите небуферизованный вывод всякий раз, когда вы хотите убедиться, что вывод был записан перед продолжением. Одним из примеров является стандартная ошибка в библиотеке времени выполнения C - это, как правило, небуферизованная по умолчанию. Поскольку ошибки (надеюсь) нечасты, вы хотите знать о них немедленно. С другой стороны, стандартный вывод и буферизуется просто потому, что предполагается, что через него будет проходить гораздо больше данных.
другой пример-библиотека журналов. Если ваш сообщения журнала хранятся в буферах в вашем процессе, и ваш процесс сбрасывает ядро, есть очень хороший шанс, что вывод никогда не будет записан.
кроме того, минимизируются не только системные вызовы, но и дисковый ввод-вывод. Допустим, программа читает файл по одному байту за раз. С небуферизованным входом вы будете выходить на (относительно очень медленный) диск для каждого байта, хотя он, вероятно, должен читать в целом блоке в любом случае (само дисковое оборудование может иметь буферы, но вы все еще выходя на контроллер диска, который будет медленнее, чем доступ в память).
при буферизации весь блок считывается в буфер сразу, а затем отдельные байты доставляются вам из буферной области (в памяти, невероятно быстро).
имейте в виду, что буферизация может принимать различные формы, например, в следующем примере:
+-------------------+-------------------+ | Process A | Process B | +-------------------+-------------------+ | C runtime library | C runtime library | C RTL buffers +-------------------+-------------------+ | OS caches | Operating system buffers +---------------------------------------+ | Disk controller hardware cache | Disk hardware buffers +---------------------------------------+ | Disk | +---------------------------------------+
вы хотите небуферизованный вывод, когда у вас уже есть большая последовательность байтов, готовых к записи на диск, и хотите избегайте дополнительной копии во второй буфер в середине.
Буферизованные выходные потоки будут накапливать результаты записи в промежуточный буфер, отправляя его в файловую систему ОС только тогда, когда накоплено достаточно данных (или
flush()просил). Это уменьшает количество вызовов файловой системы. Поскольку вызовы файловой системы могут быть дорогими на большинстве платформ (по сравнению с короткимmemcpy), буферизованный вывод является чистым выигрышем при выполнении большого количества небольших записей. Unbuffered output обычно лучше, когда у вас уже есть большие буферы для отправки-копирование в промежуточный буфер не уменьшит количество вызовов ОС дальше и введет дополнительную работу.Unbuffered выход имеет ничего для обеспечения того, чтобы ваши данные достигали диска; эта функциональность обеспечивается
flush(), и работает как на буфер и небуферизованные потоки. Небуферизованные записи IO не гарантируют, что данные достигли физического диска-файловая система ОС может свободно удерживать копию ваших данных бесконечно, никогда не записывая ее на диск, если захочет. Требуется только зафиксировать его на диске при вызовеflush(). (Обратите внимание, чтоclose()будем называтьflush()от вашего имени).
Comments