Boost.Interprocessиспользует библиотеку Windows COM для реализации некоторых функций и инициализирует её с помощью модели параллелизма<COINIT_APARTMENTTHREADED>. Если COM-библиотека уже была инициализирована вызывающим потоком для другой модели параллелизма,Boost.Interprocessсправляется с этим изящно и использует COM-призывы для уже инициализированной модели. Если по какой-то причине вы хотитеBoost.Interprocessдля инициализации библиотеки COM с другой моделью, определить макрос<BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL>Прежде чем включитьBoost.Interprocessк одному из этих значений:
Общая память (<shared_memory_object>) реализована в окнах с использованием карт памяти файлов, размещенных в общем каталоге в общей папке документов (<SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellFolders\CommonAppData>). Это имя каталога - последнее время загрузки, полученное с помощью вызовов COM (если<BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME>) определено или поиск системного журнала для запуска события (реализация по умолчанию), так что каждая общая память загрузки создается в новой папке, получающей общую память сохранения ядра.
При использовании<BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME>из-за ошибок, связанных с реализацией COM, в Boost 1.48 & Boost 1.49 папка времени загрузки была сброшена, и файлы были непосредственно созданы в общей папке документов, возвращаясь к общей памяти с сохранением файловой системы. Boost 1.50 исправил эти проблемы и восстановил время загрузки каталога и стойкость ядра. Если вам нужно воспроизвести поведение Boost 1.48 & Boost 1.49 для связи с приложениями, скомпилированными с этой версией, прокомментируйте<#defineBOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME>директиву в части конфигурации Windows<boost/interprocess/detail/workaround.hpp>.
Если использование реализации по умолчанию (28) не определено, и событие запуска не найдено, это может быть связано с некоторым программным обеспечением, которое затопляет или стирает журнал событий.
В любом случае ошибки (папка с общими документами не определена или время загрузки невозможно получить, библиотека выкидывает ошибку). Вы можете использоватьBoost.Interprocessочерняет ваш собственный каталог как общий каталог. Просто определите<BOOST_INTERPROCESS_SHARED_DIR_PATH>при использовании библиотеки, и этот путь будет использоваться для размещения общих файлов памяти.
Если<BOOST_USE_WINDOWS_H>определено,и другие файлы Windows SDK включены, в противном случае библиотека объявляет необходимые функции и структуры, чтобы уменьшить влияние включения этих тяжелых заголовков.
В системах без поддержки совместно используемой памяти POSIX объекты совместно используемой памяти реализуются в виде картированных файлов памяти, используя каталог, размещенный в "/tmp", который может включать (если<BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME>определено) последнее время загрузки (если Os поддерживает его). Как и в Windows, в любом случае ошибки при получении этого каталога библиотека выбрасывает ошибку. Можно использоватьBoost.Interprocessочерняет ваш собственный каталог как общий каталог. Просто определите<BOOST_INTERPROCESS_SHARED_DIR_PATH>при использовании библиотеки, и этот путь будет использоваться для размещения общих файлов памяти.
Обязательным адресным пространством является общее количество виртуальной памяти (своп или физическая память / оперативная память), которое ядро может предоставить, если все приложения решат получить доступ ко всей памяти, которую они запросили из ядра. По умолчанию Linux позволяет процессам создавать больше виртуальной памяти, чем доступно в системе. Если эта память недоступна, физическая память + обмен не используется.
Причина такого поведения заключается в том, что Linux пытается оптимизировать использование памяти в разветвленных процессах; форк создает полную копию пространства процесса, но с перегруженной памятью, в этом новом разветвленном экземпляре только страницы, которые были написаны, на самом деле должны быть выделены ядром. Если приложения получают доступ к большему количеству памяти, чем доступно, то ядро должно освободить память трудным способом: OOM (Out of Memory)-убийца выбирает некоторые процессы для уничтожения, чтобы восстановить память.
Boost.Interprocessне имеет возможности изменить это поведение, и пользователи могут пострадать от OOM-убийцы при доступе к общей памяти. Согласно документацииKernel, ядро Linux поддерживает несколько режимов перебора. Если вам нужны гарантии неубивания в вашем заявлении, вы должны изменить это поведение.
Многие люди внесли свой вклад в идеи и изменения, так что это место, чтобы поблагодарить их:
Спасибо всем людям, которые проявили интерес к библиотеке и скачали и протестировали снимки.
СпасибоФрэнсис АндреиАндерс Гибертцза их идеи и предложения. Многие из них еще не реализованы, но я надеюсь включить их, когда библиотека получит некоторую стабильность.
БлагодаряМартину Адриану, который предложил использовать фреймворк Interprocess для буферов, определенных пользователем.
СпасибоСинге Тодоза его патч для улучшения документации по межпроцессу.
СпасибоОлаф Крикалладля своей навязчивой библиотеки. Я взял некоторые идеи, чтобы улучшить реализацию красного черного дерева из его библиотеки.
СпасибоДаниэлю Джеймсуза его неупорядоченную_карту/набор семьи и его помощь с распределителями. Его великолепная неупорядоченная реализация была ссылкой на безопасные контейнеры.
БлагодаряГовард Хиннантза его удивительную помощь, особенно объясняющую замену распределителя, семантику перемещения и разработку обновленных функций mutex и передачи блокировки.
БлагодаряПавел Возенилекза непрерывный процесс рассмотрения, предложения, код и помощь. Является основным сторонником библиотеки Interprocess. Библиотека выросла благодаря его многочисленным советам.
И, наконец, спасибо всем бустерам.Да здравствует C++!
Удаленный<unique_ptr>, теперь перенаправляет импульс::interprocess::unique_ptr в класс общего назначения<boost::movelib::unique_ptr>изBoost.Move. Эта реализация ближе к стандартной реализации<std::unique_ptr>и лучше поддерживается.
GitHub Pull #2"Предоставить поддержку компилятора Cray C++. Компилятор Cray определяет __GNUC__"].
GitHub Pull #3«Fix/mingw interprocess_ Exception throw in file_wrapper::priv_open_or_create»].
Разрыв ABI:#9221показал, что<BOOST_INTERPROCESS_MSG_QUEUE_CIRCULAR_INDEX>опция очереди сообщений была полностью нарушена, поэтому разрыв ABI был необходим для рабочей реализации.
Упрощенный, рефакторированный и унифицированный (timed_)lock код на основе try_lock(). Было несколько ошибок при обработке истечений тайм-аута.
Изменилась реализация деструкторов переменных условий, чтобы позволить семантику POSIX (переменная состояния может быть уничтожена после пробуждения всех ожидающих потоков).
Добавлен<BOOST_INTERPROCESS_SHARED_DIR_PATH>вариант определения общего каталога, используемого для размещения объектов общей памяти при реализации в виде карт памяти файлов.
Добавлена поддержка<BOOST_USE_WINDOWS_H>. Когда этот макрос определен, Interprocess не объявляет используемую функцию и типы Windows API, включает все необходимые заголовки Windows SDK и использует типы и функции, объявленные Windows SDK.
Фиксированные баги#7156«межпроцессные буферные потоки утечивают память на конструкцию»].#7164«Два потенциальных бага с b:::int]].#7860«примитивы сикронизации на основе шпинлока»].#8277«доксы для имени_mutex ошибочно относятся к interprocess_mutex»].#8976«shared_ptr не удается компилировать, если используется с прицельным_allocator»].#9008[
Разрыв АБИ: Измененная функция загрузки в Windows для использования службы EventLog время запуска системы как время загрузки системы. Ранее используемый<LastBootupTime>из WMI был нестабилен с синхронизацией и спячкой во времени и непригоден на практике. Если вам действительно нужно получить предварительное определение поведения Boost 1.54<BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME>из командной строки или<detail/workaround.hpp>.
Разбиение ABI:Реализовано<message_queue>с круговым буферным индексом (старое поведение использовало упорядоченный массив, приводящий к избыточным копиям). Это должно значительно повысить производительность, но ломает ABI. Старое поведение/ABI может быть использовано неопределяющим макро<BOOST_INTERPROCESS_MSG_QUEUE_CIRCULAR_INDEX>в<boost/interprocess/detail/workaround.hpp>.
Улучшенное время вставки<message_queue>, позволяющее избежать приоритетного поиска общих случаев (как массивных, так и круговых буферных конфигураций).
Синхронная и асинхронная промывка<mapped_region::flush>.
Источник: ABI breakУдаленный<get_offset>метод из<mapped_region>, так как он не имеет практической полезности и<m_offset>член не был ни для чего другого.
Общая память в окнах снова имеет устойчивость ядра: загрузочный штемпель ядра и WMI получили некоторые исправления и оптимизации. Это вызывает несовместимость с Boost 1.48 и 1.49, но пользователь может комментировать<#defineBOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME>в части конфигурации окна, чтобы получить Boost 1.48 & Boost 1.49 поведение.
Фиксированные временные функции в реализациях mutex для выполнения требований POSIX:Ни при каких обстоятельствах функция не должна выходить из строя с тайм-аутом, если мутекс может быть немедленно заблокирован. Валидность параметра abs_timeout не нужно проверять, если mutex может быть заблокирован немедленно.
Добавлена поддержка настройки offset_ptr и позволяет создавать пользовательские управляемые сегменты, которые могут быть разделены между 32 и 64 битными процессами.
Общая память в окнах снова имеет срок службы файловой системы: загрузка ядра и использование WMI для получения надежной метки времени вызывали много проблем.
<shared_memory_object::remove>теперь имеет семантику POSIX<unlink>и<file_mapping::remove>был добавлен для получения семантики POSIX<unlink>с отображенными файлами.
Общая память в Windows теперь имеет срок службы ядра вместо срока службы файловой системы: общая память исчезнет при перезагрузке системы.
Контейнеры можно использовать в рекурсивных типах.
Добавлена<BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION>опция макроса для принудительного использования общего кода эмуляции для примитивов синхронизации с общим процессом вместо нативных функций POSIX.
Добавлены в контейнеры вставные элементы размещения
<boost::posix_time::pos_inf>значение теперь обрабатывается переносимо для функций времени.
Обновить некоторые параметры функций от<iterator>до<const_iterator>в контейнерах, чтобы не отставать от проекта следующего стандарта.
Добавлены вспомогательные утилиты для облегчения определения и построения<shared_ptr>,<weak_ptr>и<unique_ptr>. Добавлены пояснения и примеры этих умных указателей в документации.
Оптимизированный вектор:
1) В настоящее время максимально возможна работа с необработанными указателями при использовании распределителей, определяющих<pointer>как умный указатель. Это повышает производительность и улучшает время компиляции.
2) Немного метапрограммирования, чтобы избежать использования move_iterator, когда тип имеет тривиальный конструктор копий или назначение и улучшает производительность.
3) Изменены пользовательские алгоритмы со стандартными для использования оптимизированных стандартных алгоритмов.
4) Снят неиспользованный код.
Разрыв АБИ: Контейнеры не происходят от распределителей, чтобы избежать проблем с распределителями, которые могут определять виртуальные функции с теми же названиями, что и функции контейнеров. Это преобразует функции контейнера в виртуальные функции и может запретить некоторые из них, если возвращенный тип не приводит к ковариантному возврату. Распределители теперь хранятся как базовые классы внутренних структур.
Уменьшенное раздувание шаблона для узла и адаптивные распределители, извлекающие реализацию узла в класс, который зависит только от алгоритма памяти, вместо менеджера сегмента + размера узла + номера узла.
Исправлена ошибка<mapped_region>в UNIX при предоставлении адреса отображения, но область была отображена в другом адресе.
Исправлена ошибка субоптимального расширения буфера в<rbtree_best_fit>.
Добавлена итерация названных и уникальных объектов в менеджере сегментов.
Утечка в<vector>.
Добавлена поддержка Solaris.
Оптимизирован<segment_manager>, чтобы избежать вздутия кода, связанного с шаблонными инстанциациями.
Исправленная ошибка для UNIX: No slash ('/') был добавлен в качестве первого символа для общих имен памяти, что привело к ошибкам в некоторых системах UNIX.
Исправленная ошибка в VC-8.0: Сломанная функция, находящаяся в функциях ядра offset_ptr.
Примеры кода изменены для использования новых функций импорта кода BoostBook.
Добавлена функция распределения памяти к алгоритмам памяти.
Улучшенные (много)карты/(много) набора конструкторов, принимающих итераторы. Теперь они имеют линейное время, если диапазон итератора уже отсортирован.
Разрушение ABI: (много)map/(много)set теперь уменьшают размер их узла. Цветовой бит встроен в родительский указатель. Размер узла — это размер 3 указателей в большинстве систем. Эта оптимизация активируется для необработанных и<offset_ptr>указателей.
(multi)map/(multi)set теперь повторно использует память от старых узлов в операторе назначения.
Разрыв АБИ: Внедренные узлы-контейнеры на основе интрузивных контейнеров. Это экономит размер кода, так как многие инстанциации используют одни и те же алгоритмы.
Исправленный код компилируется с Visual C++ 8.0.
Добавлена функция нулевой свободной памяти в алгоритмах памяти и менеджере сегментов. Эта функция полезна по соображениям безопасности и для улучшения коэффициентов сжатия файлов, созданных с помощью<managed_mapped_file>.
Добавлена поддержка интрузивных типов индексов в управляемых сегментах памяти. Интрузивные индексы сохраняют дополнительные выделения памяти для выделения индекса, так как только с одним выделением мы выделяем место для значения, имени и крючка для вставки объекта в индекс.
Создан новый тип индекса:iset_index. Это индекс, основанный на навязчивом наборе (rb-дерево).
Создан новый тип индекса:iunordered_set_index. Это индекс, основанный на псевдонавязчивом неупорядоченном наборе (hash table).
ABI break: Навязчивый индексiset_indexтеперь является типом индекса по умолчанию.
Оптимизированный вектор для использования<boost::has_trivial_destructor>. Эта оптимизация позволяет избежать вызова деструкторов элементов, которые имеют тривиальный деструктор.
Оптимизированный вектор, чтобы воспользоваться чертой<has_trivial_destructor_after_move>. Эта оптимизация позволяет избежать вызова деструкторов элементов, которые имеют тривиальный деструктор, если элемент был перемещен. Этот трюк был предоставлен Говардом Хиннантом.
Добавлена проверка безопасности, чтобы избежать целочисленной ошибки переполнения в распределителях и названных функциях строительства.
Добавлены проверки выравнивания для функций расширения вперед и назад.
Фиксированная ошибка в атомных функциях для PPC.
Исправлена ошибка состояния гонки при создании и открытии управляемого сегмента.
Добавлены адаптивные бассейны.
Разрыв источника: Изменение порядка параметров шаблона распределителей узлов, чтобы сделать их более простыми в использовании.
Добавлена поддержка нативных окон общей памяти.
Добавлено больше тестов.
Исправлено наличие частных функций в справочном разделе.
Добавлена функция<deallocate_free_chunks()>для ручного раскладывания полностью свободных кусков от распределителей узлов.
Осуществленное предложение N1780 по вопросу 233:Вставка намекает в ассоциативные контейнерыв интерпроцессные<multiset>и<multimap>классы.
Разрыв источника: В настоящее время используется объект общей памяти, включающий заголовок<shared_memory_object.hpp>вместо<sharedmemory.hpp>.
Разрыв АБИ: Изменился глобальный mutex при инициализации управляемой совместной памяти и карт памяти файлов. Это изменение пытается минимизировать тупики.
Разрыв источника: Изменилась общая память, отображались файлы памяти и отображался открытый режим области для одного<mode_t>типа.
Добавлено дополнительно WIN32_LEAN_AND_MEAN перед включением заголовков DateTime, чтобы избежать ошибок переопределения сокетов при использовании Interprocess и Asio в окнах.
ABI break:<mapped_region>Конструктор больше не требует классов, полученных из Memory_mappable, но классы должны соответствовать концепции MemoryMappable.
Добавлены возможности перераспределения на месте в basic_string.
ABI break: Реализована и оптимизирована оптимизация малых строк. Узкий струнный класс имеет нулевые байтовые накладные расходы с внутренним 11-байтовым буфером в 32 системах.
Добавлена семантика перемещения в контейнеры. Улучшает производительность при использовании контейнеров.
ABI break: Конечные узлы контейнеров узлов (список, список, карта/набор) теперь встроены в контейнеры вместо выделения с помощью распределителя. Это позволяет не бросать ход-конструкторы и улучшает производительность.
ABI break:slistиlistконтейнеры теперь имеют размер в постоянное времяфункция. В качестве члена добавляется размер контейнера.
Некоторые полезные ссылки на язык программирования C++, внутренние компоненты C++, общую память, распределители и контейнеры, используемые для проектированияBoost.Interprocess.
Есть некоторые функции, которые я хотел бы реализовать, и некоторые.Boost.Interprocessкод, который может быть намного лучше. Давайте посмотрим на некоторые идеи:
Версия Win32 общих мутексов и общих условий основана на атомных инструкциях «вращение и ожидание». Это приводит к плохой производительности и не решает никаких проблем, таких как приоритетные инверсии. Нам потребуется очень серьезная помощь со стороны экспертов по этому вопросу. И я не уверен, что это может быть достигнуто в программном обеспечении пользовательского уровня. Реализации на основе Posix используют атрибут PTHREAD_PROCESS_SHARED для размещения мутексов в общей памяти, поэтому таких проблем нет. Я не знаю ни одной реализации, которая имитирует атрибут PTHREAD_PROCESS_SHARED для Win32. Мы должны быть в состоянии построить эти примитивы в картированных файлах памяти, чтобы мы могли получить устойчивость файловой системы так же, как с примитивами POSIX.
В настоящее время Interprocess позволяет использовать толькоcharдля базовых названных объектов. Однако несколько операционных систем используютwchar_tимена для ресурсов (например, картированные файлы). В будущем Interprocess должен попытаться представить портативный узкий/широкоугольный интерфейс. Для этого было бы полезно иметь утилиты преобразования строк для перевода имен ресурсов (избегая необходимых символов, которые могут конфликтовать с именами ОС) портативным способом. Было бы интересно также использоватьboost::filesystemPaths, чтобы избежать проблем с операционной системой.
Boost.Interprocessне определяет атрибуты безопасности для совместно используемой памяти и объектов синхронизации. Стандартный C++ также игнорирует атрибуты безопасности с файлами, поэтому добавление атрибутов безопасности потребует серьезной работы.
Boost.Interprocessпредлагает общую для процесса очередь сообщений на основеBoost.Interprocessпримитивы, такие как мутексы и условия. Я хотел бы разработать больше механизмов, таких как потоково-ориентированный fifo, чтобы мы могли использовать его с оберткой iostream-интерфейса (мы можем имитировать трубы Unix).
C++ нуждается в более сложных механизмах, и было бы неплохо иметь в C++ механизм, ориентированный на поток и дейтаграмму PF_UNIX. А для очень быстрых межпроцессных удаленных вызовов Solaris door — интересная альтернатива реализации для C++. Но работа по внедрению PF_UNIX-подобных розеток и дверей будет огромной (и это может быть трудно в библиотеке пользовательского уровня). Кто-нибудь из сетевых экспертов?
Статья Acknowledgements, notes and links раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 16. Boost.Interprocess может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.