Файлы с отображением памяти на C ++ [дубликат]

Чтобы определить, почему код PHP не работает в коде JavaScript , нам нужно понять, что такое клиентский и серверный язык и как они работают.

Серверные языки (PHP и т. д.) : они извлекают записи из баз данных, поддерживают состояние через HTTP-соединение без состояния и выполняют много вещи, требующие безопасности. Они находятся на сервере, эти программы никогда не имеют своего исходного кода для пользователя

Image from wikipedia_http://en.wikipedia.org/wiki/File:Scheme_dynamic_page_en.svg [/g16] image attr

Хотя с другой стороны Клиентский язык на стороне клиента (например, JavaScript) находится в браузере и запускается в браузере, Сценарии на стороне клиента обычно относятся к классу компьютерных программ в Интернете, которые выполняются на стороне клиента, в веб-браузере пользователя, а не на стороне сервера .

JavaScript отображается пользователю и может быть легко изменен, поэтому для обеспечения безопасности мы не должны полагаться на JavaScript.

Итак, когда вы делаете запрос HTTP на сервере, чем сервер, сначала внимательно читает файл PHP, чтобы узнать, есть ли какие-либо задачи, которые необходимо выполнить, и отправлять ответ на клиентскую сторону и снова, как @deceze сказал * Как только PHP закончил вывод ответа, сценарий заканчивается, и на сервере ничего не произойдет, пока не появится новый запрос HTTP . *

Graphical representation [/g17]

Источник изображения

Итак, что мне делать, если мне нужно вызвать PHP? Это зависит от того, как вам это нужно: либо перезагружая страницу, либо используя вызов AJAX.

  1. Вы можете выполнить перезагрузку страницы и отправить запрос HTTP
  2. вы можете сделать вызов AJAX с помощью JavaScript, и это не требует перезагрузки страницы

Хорошо Чтение:

  1. Википедия:
  2. Википедия: скрипты на стороне клиента
  3. Мадара Учиха: разница между клиентской стороной и программированием на стороне сервера

232
задан Peter Burns 3 November 2008 в 08:56
поделиться

5 ответов

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

mmap также позволяет операционной системе оптимизировать операции подкачки. Например, рассмотрите две программы; программа A, которая считывает файл 1 МБ в буфер, создавая с помощью malloc, и программу B, которая копирует 1 МБ-файл в память. Если операционная система должна поменять часть памяти A, она должна записать содержимое буфера для свопинга, прежде чем он сможет повторно использовать память. В случае B любые немодифицированные страницы mmap'd могут быть повторно использованы сразу, потому что ОС знает, как их восстановить из существующего файла, из которого они были mmap'd. (ОС может определить, какие страницы не модифицированы, изначально отмечая записываемые mmap'd-страницы как только для чтения и ломая seg-ошибки, аналогичные стратегии Copy on Write).

mmap также полезен для взаимодействия между процессами. Вы можете mmap файл как чтение / запись в процессах, которые должны связываться, а затем использовать примитивы sychronization в области mmap'd (для этого используется флаг MAP_HASSEMAPHORE).

Одно место mmap может быть неудобно, если вам нужно работать с очень большими файлами на 32-битной машине. Это связано с тем, что mmap должен найти непрерывный блок адресов в адресном пространстве вашего процесса, который достаточно велик, чтобы соответствовать всему диапазону отображаемого файла. Это может стать проблемой, если ваше адресное пространство будет фрагментировано, где у вас может быть свободное место на 2 ГБ адресного пространства, но ни один отдельный диапазон его не может соответствовать отображению файла 1 ГБ. В этом случае вам может понадобиться сопоставить файл меньшими фрагментами, чем вы хотели бы сделать его пригодным.

Еще одна потенциальная неловкость с mmap в качестве замены для чтения / записи заключается в том, что вы должны начать свое отображение на смещения размера страницы. Если вы просто хотите получить некоторые данные со смещением X, вам нужно будет исправить это смещение, чтобы оно совместимо с mmap.

И, наконец, чтение / запись - это единственный способ работы с некоторыми типами файлов. mmap не может использоваться на таких вещах, как трубы и ttys.

260
ответ дан Don Neufeld 24 August 2018 в 23:46
поделиться
  • 1
    Можете ли вы использовать mmap () для растущих файлов? Или размер фиксирован в точке, когда вы выделяете память / файл mmap ()? – Jonathan Leffler 4 November 2008 в 00:44
  • 2
    Когда вы делаете вызов mmap, вы должны указать размер. Поэтому, если вы хотите сделать что-то вроде операции с хвостом, это не очень удобно. – Don Neufeld 4 November 2008 в 03:13
  • 3
    Afaik MAP_HASSEMAPHORE специфичен для BSD. – Patrick Schlüter 24 May 2010 в 09:13
  • 4
    @JonathanLeffler Конечно, вы можете использовать mmap () для растущих файлов, но вам нужно снова вызвать mmap () с новым размером, когда файл достигнет предела места, которое вы первоначально выделили. Уровень PosixMmapFile от LevelDB дает вам хороший пример. Но он прекратил использование mmap с 1,15. Вы можете получить старую версию из Github – baotiao 4 March 2015 в 10:16
  • 5
    mmap также может быть полезен, если файл нужно обрабатывать несколькими проходами: стоимость размещения страниц виртуальной памяти оплачивается только один раз. – Jib 7 December 2016 в 14:26

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

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

7
ответ дан AndyG 24 August 2018 в 23:46
поделиться
  • 1
    Обратите внимание, что mmap () не всегда быстрее, чем read (). Для последовательных чтений mmap () не даст вам никаких измеримых преимуществ - это основано на эмпирических и теоретических доказательствах. Если вы мне не верите, напишите свой тест. – Tim Cooper 9 December 2008 в 05:40
  • 2
    Я могу указать числа, поступающие из нашего проекта, своего рода текстовый индекс для базы данных фразы. Индекс составляет несколько гигабайт, а ключи хранятся в тройном дереве. Индекс все еще растет параллельно доступу чтения, доступ за пределами отображаемых частей осуществляется через pread. В Solaris 9 Sparc (V890) доступ к pread между 2 и 3 раза медленнее, чем memcpy из mmap. Но вы правы, что последовательный доступ не обязательно быстрее. – Patrick Schlüter 24 May 2010 в 09:25
  • 3
    Просто маленькая nitpick. Он не работает, как механизм поискового вызова, это механизм поискового вызова. При сопоставлении файла назначается область памяти для файла вместо анонимного файла подкачки. – Patrick Schlüter 24 May 2010 в 09:59

Одна область, где я нашел mmap (), чтобы не быть преимуществом, - это чтение небольших файлов (до 16K). Накладные расходы на ошибку страницы для чтения всего файла были очень высокими по сравнению с простое выполнение одного системного вызова read (). Это связано с тем, что ядро ​​иногда может усвоить прочитанное полностью в вашем временном фрагменте, то есть ваш код не отключается. С ошибкой страницы казалось более вероятным, что другая программа будет запланирована, что сделает операцию файла более высокой.

56
ответ дан Ben Combee 24 August 2018 в 23:46
поделиться
  • 1
    +1 Я могу это подтвердить. Для небольших файлов быстрее malloc кусок памяти и делает 1 read. Это позволяет иметь тот же код, который обрабатывает карты памяти, обрабатываемые malloc'ed. – Patrick Schlüter 24 May 2010 в 09:18
  • 2
    Это говорит о том, что ваше оправдание в этом неверно. Планировщик не имеет ничего общего с разницей. Разница заключается в доступе на запись к таблицам страниц, который представляет собой глобальную структуру ядра, в которой хранятся какие процессы хранятся на странице памяти и ее правах доступа. Эта операция может быть очень дорогостоящей (она может быть лишена линий кэша, она может пропустить TLB, таблица глобальна, поэтому ее нужно защищать от одновременного доступа и т. Д.). Вам нужен определенный размер карты, чтобы накладные расходы на read были выше, чем накладные расходы на обработку виртуальной памяти. – Patrick Schlüter 24 May 2010 в 09:36
  • 3
    @ PatrickSchlüter Хорошо, я понимаю, что в начале mmap () есть накладные расходы, что связано с изменением таблицы страниц. Скажем, мы отображаем 16K файла в память. Для размера страницы 4K, mmap должен обновить 4 записи в таблице страниц. Но использование read для копирования в буфер 16K также включает в себя обновление записей в 4 страницы таблицы, не говоря уже о необходимости копирования 16K в пользовательское пространство addr. Не могли бы вы рассказать о различиях операций на странице таблицы и о том, как это дорого для mmap? – flow2k 24 August 2018 в 07:44

mmap имеет преимущество, когда у вас есть случайный доступ к большим файлам. Другим преимуществом является то, что вы обращаетесь к нему с операциями памяти (memcpy, арифметикой указателей), не беспокоясь о буферизации. Обычный ввод-вывод иногда может быть довольно сложным при использовании буферов, когда у вас есть структуры, большие, чем ваш буфер. Код для обработки, который часто трудно получить, mmap обычно проще. Это говорит о том, что при работе с mmap есть определенные ловушки. Как уже упоминалось, mmap достаточно дорогостоящим, поэтому стоит использовать только для заданного размера (от машины к машине).

Для чистого последовательного доступа к файлу это также не всегда лучшее решение, хотя соответствующий вызов madvise может уменьшить проблему.

Вы должны быть осторожны с ограничения на выравнивание вашей архитектуры (SPARC, itanium), с IO для чтения / записи, буферы часто правильно выравниваются и не ловутся при разыменовании литого указателя.

Вы также должны быть осторожны, чтобы не получить доступ вне карты. Это легко осуществить, если вы используете строковые функции на своей карте, и ваш файл не содержит \ 0 в конце. Он будет работать большую часть времени, когда размер вашего файла не будет кратным размеру страницы, так как последняя страница заполнена 0 (отображаемая область всегда имеет размер кратного размера вашей страницы).

39
ответ дан Patrick Schlüter 24 August 2018 в 23:46
поделиться

В дополнение к другим приятным ответам цитата из системного программирования Linux , написанная экспертом Google Робертом Лав:

Преимущества mmap( )

Манипулирование файлами через mmap( ) имеет несколько преимуществ перед стандартными системными вызовами read( ) и write( ). Среди них:

  • Чтение и запись в файл с отображением памяти позволяет избежать посторонней копии, которая возникает при использовании системных вызовов read( ) или write( ), где данные должны быть скопированы в и из буфера пользовательского пространства.
  • Помимо любых возможных ошибок страницы, чтение и запись в файл с отображением памяти не несет каких-либо системных вызовов или служебных сообщений коммутатора контекста. Это так же просто, как доступ к памяти.
  • Когда несколько процессов сопоставляют один и тот же объект в памяти, данные распределяются между всеми процессами. Сопоставления только для чтения и совместного доступа доступны для совместного использования; частные записи, доступные для записи, имеют свои страницы с не-пока-COW (копирование на запись).
  • Поиск вокруг отображения включает тривиальные манипуляции с указателями. Системный вызов lseek( ) не нужен.

По этим причинам mmap( ) является разумным выбором для многих приложений.

Недостатки mmap( )

При использовании mmap( ) следует иметь в виду несколько моментов:

  • Отображения памяти всегда представляют собой целое число страниц в размере. Таким образом, разница между размером файла резервной копии и целым числом страниц «потеряна» в качестве незаполненного пространства. Для небольших файлов значительная часть картирования может быть потрачена впустую. Например, с страницами 4 КБ, 7-байтовое отображение отходов составляет 4089 байт.
  • Отображения памяти должны вписываться в адресное пространство процесса. С 32-разрядным адресным пространством очень большое количество отображений различного размера может привести к фрагментации адресного пространства, что затрудняет поиск больших свободных смежных областей. Эта проблема, конечно, гораздо менее очевидна с 64-разрядным адресным пространством.
  • В создании и обслуживании сопоставлений памяти и связанных структур данных внутри ядра возникают накладные расходы. Эти служебные данные, как правило, устраняются устранением двойной копии, упомянутой в предыдущем разделе, особенно для файлов с большими и часто доступными файлами.

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

9
ответ дан Toby Speight 24 August 2018 в 23:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: