Повышение:: межпроцессный готовый к прайм-тайму? [закрытый]

12
задан MrEvil 7 July 2010 в 15:40
поделиться

2 ответа

Я попытался использовать boost :: interprocess для проекта и ушел со смешанными чувствами. Мое главное опасение - это дизайн boost :: offset_ptr и то, как он обрабатывает значения NULL - короче говоря, boost :: interprocess может сделать диагностику ошибок указателей NULL по-настоящему болезненной. Проблема в том, что сегмент разделяемой памяти отображается где-то в середине адресного пространства вашего процесса, а это означает, что значение offset_ptr "NULL" при разыменовании будет указывать на допустимое место в памяти, поэтому ваше приложение не будет segfault. Это означает, что когда ваше приложение наконец выйдет из строя, может пройти много времени после того, как была сделана ошибка, что очень усложняет отладку.

Но становится еще хуже. Мьютексы и условия, которые внутренне использует boost ::: interprocess, хранятся в начале сегмента. Поэтому, если вы случайно напишете в some_null_offset_ptr-> some_member, вы начнете перезаписывать внутренний механизм сегмента boost :: interprocess и получите совершенно странное и трудное для понимания поведение. Написание кода, который координирует несколько процессов и справляется с возможными условиями гонки, может быть трудным само по себе, поэтому это вдвойне сводило с ума.

Я закончил тем, что написал свою собственную минимальную библиотеку разделяемой памяти и использовал системный вызов POSIX mprotect, чтобы сделать первую страницу моих сегментов разделяемой памяти нечитаемой и недоступной для записи, что привело к немедленному появлению ошибок NULL (вы тратите страницу памяти, но такая небольшая жертва того стоит, если только вы не используете встроенную систему).Вы можете попробовать использовать boost :: interprocess, но по-прежнему вручную вызывать mprotect, но это не сработает, потому что boost будет ожидать, что он сможет записывать внутреннюю информацию, которую он хранит в начале сегмента.

Наконец, offset_ptr предполагает, что вы храните указатели в сегменте общей памяти на другие точки в том же сегменте общей памяти. Если вы знаете, что у вас будет несколько сегментов разделяемой памяти (я знал, что это будет так, потому что для меня, потому что у меня был один доступный для записи сегмент и 1 сегмент только для чтения), которые будут хранить указатели друг в друге, offset_ptr встанет у вас на пути и вам нужно сделать кучу ручных преобразований. В моей библиотеке общей памяти я создал шаблонный класс SegmentPtr , где SegmentPtr <0> будет указателем на один сегмент, SegmentPtr <1> будет указатели на другой сегмент и т.д., чтобы их нельзя было перепутать (вы можете сделать это, только если вы знаете количество сегментов во время компиляции).

Вам нужно взвесить стоимость реализации всего самостоятельно по сравнению с дополнительным временем отладки, которое вы собираетесь потратить на отслеживание ошибок NULL и возможное смешивание указателей на разные сегменты (последнее не обязательно является проблемой для вас). Для меня стоило реализовать что-то самостоятельно, но я не сильно использовал структуры данных, которые предоставляет boost :: interprocess, так что это явно того стоило.Если в будущем библиотеке будет разрешено быть открытым исходным кодом (не до меня), я обновлю ссылку, но пока не задерживайте дыхание; p

Что касается вашего коллеги: я не испытывать нестабильность или ошибки в самом boost :: interprocess. Я просто думаю, что его дизайн затрудняет поиск ошибок в вашем собственном коде.

20
ответ дан 2 December 2019 в 06:07
поделиться

Мы используем boost::interprocess shared memory и interprocess.synchronization_mechanisms.message_queue уже около 6 месяцев и нашли код надежным, стабильным и довольно простым в использовании.

Мы храним наши данные в довольно простых структурах фиксированного размера (хотя 12 регионов общим размером 2+гб) и мы использовали код примера boost::interprocess как есть и практически не имели проблем.

Мы обнаружили два момента, на которые следует обратить внимание при использовании boost::interprocess с windows.

  1. Просмотрите Boost Shared Memory & Windows. Если вы используете объекты по умолчанию #include , то увеличить размер области отображения памяти можно только перезагрузив сначала Windows. Это связано с тем, как boost использует резервное хранилище файлов.
  2. Класс message_queue использует по умолчанию объект shared_memory_object. Поэтому, если размер сообщения нужно увеличить, снова перезагрузите Windows.

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

5
ответ дан 2 December 2019 в 06:07
поделиться
Другие вопросы по тегам:

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