Как стать автором
Обновить

Комментарии 25

Интересная статья, хотелось бы ещё узнать про mapped_file_* из <boost/iostreams/device/mapped_file.hpp>, а именно есть ли отличия по скорости, в каком-либо конкретном случае. Так же есть вопрос, когда мы маппим большой файл в 32-х разрядной системе, как мы можем узнать максимальный кусок для маппинга? На моей машине выходит в районе 1-2Гб практическим путём.
Размер отображения файла в память имеет ограничение сверху как доступный диапазон адресов памяти. Обычно 32-х разрядное приложение ограничено 2Гб диапазоном свободных адресов виртуальной памяти.
Поэтому в 32-х разрядных приложениях маппинг больших файлов лучше производить через скользящее окно фиксированного размера, а не стараться отобразить весь большой файл в доступное вам пространство.
Для 64-х битных программ ограничение по адресному пространству конечно тоже есть, только оно настолько большое, что можно говорить о бесконечном адресном пространстве.
только оно настолько большое, что можно говорить о бесконечном адресном пространстве.

Вот только у нас есть нюанс в виде расходов на хранение таблицы страниц. На каждую 4-килобайтную страницу приходится по 4 байта метаданных.

Это так. Технически и адреса не полностью 64-х битные и у процессора и у операционной системы есть свои ограничения. Итого 4 Пб теоретически адресуемых и 1-2Тб фактически поддерживаемых современными процессорами, ОС и аппаратурой. Следовательно имеем ограничение 1-2Тб на непрерывный участок отображения файла в память для 64-х битных процессов.
Про скорость: операции отображения в память (mmap) являются ленивыми, то есть время их выполнения не зависит от размера запрошенного маппинга. Чуть подробнее — когда вы делаете mmap, операционная система просто помечает, что определённые адреса должны отображаться на файл, возвращает вам управление и работа вашей программы продолжается (а ОС пытается предугадать и прочитать нужные вам данные с диска). Когда ваша программа обращается к адресу, данные для которого ещё не прочитаны с диска, ОС остановит выполнение вашего приложения, прочитает данные, вернёт управление вашему приложению.

Про размер: очень зависит от платформы, многие ОС вообще не предоставляют данный функционал в удобном виде :(
Спасибо за ответ, заметил ещё одну деталь, но почему-то не нашёл её описание, если к примеру мне нужно замаппить файл размером 200Гб на x86_32 на Windows, но при этом явно указать в mapped_region конструкторе параметры offset = 0 и size = 200Гб, то исключения не вылетит и файл мапнется, но при вызове метода get_size(), вернёт кусок, который получилось замаппить, разумеется он будет менее 200-т Гб. Соответственно вопрос в том, насколько такой метод получения максимального размера маппинга переносим?
UPD: не важно, только что понял что там стоит size_t значение на кол-во байт, и он обрезает моё 64-х битное значение до 32-х бит при компиляции на x32.

И ни слова про юникод! Ну как так можно?

Исправляюсь:
filesystem::path из Boost и из C++ Standard Library умеют работать с юникодными путями:
boost::filesystem::path my_path(L"Привет мир.txt");

Так что итерирование по директориям, создание/удаление файлов/ссылок работают из коробки.

А вот с чтением файлов дела обстоят похуже:
* std::fstream умеет работать с std::filesystem::path, но не умеет работать с boost::filesystem::path. Если используете Boost версию, придется использовать boost::filesystem::fstream
* boost::interprocess работает только с char*. На POSIX (Linux) это позволяет вам задавать UTF-8 пути, а на Windows — подобное не работает.
Электронный вариант книги планируется?
Есть электронный вариант, но на английском :(
На русском он вроде как в ближайшее время не планируется :(
Мне тут издательство подсказало, что электронный вариант есть:
Выбрать PDF покупатели могут на стадии оформления заказа, когда заполняют адрес доставки или выбирают самовывоз со склада в Москве. Ниже есть поле с пометкой о PDF. Он стоит также, как и бумажная версия.
Отличная статья! Спасибо!
Было бы здорово так же про boost asio и корутины подобные статьи увидеть.
Точно! Нам же дали промокод от издательства. Добавили в конец статьи, спасибо!

Я уже заказал на ozon, не хочется с почтой связываться — а ozon послезавтра привезёт — тоже скидку даёт 100р.


Очень нравятся статьи и выступления Антона, не могу не поддержать копеечкой его труды!

Антон, здравствуйте. Можете, пожалуйста, показа какие нибудь очень крутые кейсы с новыми фичами из 20го стандарта (написать пост)? Ни у кого не получается так интересно как у Вас. =). Вчера как раз вышла новая версия MSVC в которой они реализовали все крупные фичи.
Спасибо! Не уверен что прям в ближайшее время успею написать пост (надо ведь уже о C++23 рассказывать), но постараюсь что-нибудь придумать.
Спасибо! Очень приятно :)
небольшой вопрос, с приходом с++17 необходимость в этой либе boost'a отпадает или есть как обычно что-то, что не протащили в стандарт и оно полезно?
В стандарт протащили практически всё, кроме небезопасных вещей (
boost::filesystem::unique_path
), которые не стоит использовать.

Однако filesystem до сих пор мало где реализован в стандартных библиотеках, так что Boost реализация будет востребована ещё какое-то время.
спасибо)

А как на счёт обработки ошибок? Я как то год назад написал кастомный стрим на mmap, а потом на ревью был справедливо закидан помидорами(ссылками на майллисты и статьи) где куча людей обоснованно доносили, что как только у вас есть две и более библиотеки(в одном процессе) которые что то mmapят и подходят к этому ответственно с обработкой ошибок, то у вас не просто УБ, а отдельный котел в аду под названием глобальный обработчик сигналов, который впринципе "правильно" не приготовить. Я к тому что ммап можно использовать безопасно, но только когда есть только одна библиотека, а это почти наверняка не вариант для большого проекта с длинной историей и который использует сразу много больших библиотек. Например культю и буст и тогда готовьтесь к увлекательному дебагу. Ну и как обычно в таких статьях описан самый простой хэпи пас, но хотя бы самую простую ситуацию разберите — читаете из замапленного файла с усб диска, а пользователь, вопреки всем сообщениям ОС, сука такая взял и выдернул флеху и что будет при использовании этой либы? Вариант чуть посложнее — как добавить данные в конец файла? А что если свободного места вдруг не стало, ну например другой процесс записал что то на диск. Тут же все ленивое и преподносится типа как безусловно лучше чем не ленивое. В общем мне как написавшему свой полностью работоспособный стрим и юнит тесты и все такое, а потом выкинувшему все к хренам по причине невозможности правильной работы с ошибками очевидно что статья — не зачёт, даже 10% всей мякотки не раскрывает.

Спасибо, очень дельное замечание!

С обработкой ошибок у mmap всё и правда плохо. Если вы собираетесь работать с флешками, или кто-то может вызвать truncate для файла с которым вы работаете, или возможна ситуация что диск закончится и проч. — mmap вам не подойдёт как инструмент.

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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий