На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> Буферизация при чтении функциями С и Win32
    Меня заинтересовал вопрос о буферизации ввода-вывода и я решил попробовал проверить, так ли я все понимаю, на конкретной программе. В ней читается один и тот же файл функциями С и Win32 с включенной буферизацией и выключенной. Удобно смотреть, как это работает, на примере чтения небольшого файла (я смотрел на файле 10 мб) с CD. Функция Win32 CreateFile действительно отключает буферизацию (файл читается с диска постоянно, индикатор горит), а функция setvbuf буферизацию не отключает (файл читается один раз, индикатор гаснет, но в программе чтение происходит). Правильно ли я понимаю принципы работы этой программы в Windwows (программу прилагаю):
    1. Windows выделяет свои буферы для операций чтения-записи файла в рамках функции CreateFile . Если я отключаю буферизацию, а в программе использую свой буфер, то windows создает в памяти только буфер, который я выделяю в своей программе, никаких других буферов не используется. В связи с этим все время читается файл с диска CD.
    2. Если я буферизацию не отключаю, то Windows при работе функции CreateFile выделяет свои буферы (буфер1) (интересно, исходя из каких принципов определяется размер этих буферов) и, кроме того, создает буфер, который я выделяю в своей программе (буфер2). При чтении файл читается в буфер1 и, если он умещается целиком, далее в буфер2 он читается из буфера1. Поэтому индикатор дисковода не горит.
    3. Я думал, что при использовании функции С будут достигаться те же результаты, что и при использовании функций Win32 (думал, что при компиляции в exe идут вызовы функций Win32) и думал, что setvbuf отключает буферизацию Windows (bufer1). Однако, как показывает программа, это не так (если я все правильно делаю).
    Покритикуйте, пожалуйста, мои взгляды на буферизацию и объясните, пожалуйста, почему не работает setvbuf.
    Прикреплённый файлПрикреплённый файлBufer.zip (28.79 Кбайт, скачиваний: 106)
      Во-первых, я уже говорил, что setvbuf не имеет и не может иметь никакого отношения к буферизации ОС. Сам подумай - FILE_FLAG_NO_BUFFERING можно задать только при открытии файла CreateFile, а setvbuf можно использовать только для уже открытого файла. Поэтому если бы в C была возможность отключать буферизацию ОС, то она должна была бы сидеть в параметрах fopen, но никак не в функциях, работающих с уже открытым файлом.

      Во-вторых, не путай функции приложения и ОС. Грубо говоря к ОС относится функции ядра и та часть юзермодного АПИ, на которую ты или не можешь повлиять вообще или только в пределах, представляемых этим АПИ. В частности буферизацию файлов в ОС можно только включить\выключить (FILE_FLAG_NO_BUFFERING) и косвенно\частично повлиять на механизм буферизации (FILE_FLAG_SEQUENTIAL_SCAN), но все тонкости буферизации ОС оставляет за собой. Все остальное относится к самому приложению, в т.ч. и fopen и setvbuf - хочешь используй, хочешь не используй или вообще пиши на чистом АПИ, хочешь используй свой буфер, хочешь не используй. Поэтому не "windows создает буфер, который я использую в программе", а ты сам создаешь этот буфер, используя средства АПИ или С\С++. Ну и функции С это ес-но просто часть кода твоего приложения, написанная за тебя добрыми дядями с целью упрощения\унификации\портируемости и т.д.и т.п.

      В-третьих, судя по твоему коду, похоже ты не понял предназначение setvbuf. Не понимаю, как тебе пришло в голову выделить буфер, назначить его в setvbuf и затем в него же читать fread ?! :wacko: Буферирование стрима нужно только при чтении текстовых файлов и малых порций двоичных данных (например, в дельфи\паскале для двоичных файлов внутренняя буферизация вообще не предусмотрена - только для текстовых). В этом сл.увеличение размера буфера положительно сказывается на производительности, т.к. уменьшается число обращений к ReadFile и связанных с эти накладных расходов на переключение юзер-мод\кернел-мод. Если же есть возможность\желание читать двоичные данные большими блоками, то логичнее отключать буферизацию стрима установкой _IONBF и читать данные прямо в свой буфер.
        Спасибо большое за подробное объяснение, видимо, мне надо поглубже разобраться с понятиями ввода-вывода в С (С++) и ОС. Сейчас у меня какая-то каша в голове, буду приводить голову в порядок.
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0.0706 ]   [ 16 queries used ]   [ Generated: 8.06.26, 21:22 GMT ]