LINUX.ORG.RU

Динамические структуры данных в shared memory.

 , , ,


0

5

Всем привет. Интересует вопрос возможности создания динамический структур данных в разделяемой памяти, либо альтернативы этому.

Есть демон. Один main-процесс и несколько форкнутых воркеров. В качестве IPC используется разделяемая память. Через shmat выделяется кусок памяти, где хранятся общие используемые структуры. Все устраивает, кроме одного, нельзя использовать STL-контейнеры. Приходится делать все на обычных массивах и наступать на ограничения, которые связаны с этим.

Некоторые «workaround», которые пришли в голову:

  • Использовать boost::ipc. Писать свои кастомные алокаторы.
  • Не форкаться. Создавать треды, тогда контейнеры использовать можно, нужно лишь позаботиться об мьютексах и т.д. и т.п.
  • Не использовать разделяемую память. Поставить тот же Redis и хранить все в нем.

Есть ли еще какие-то варианты в моем случае?

Заранее спасибо за ответы.

Ответ на: комментарий от quest

Placement new будет недостаточно - нужен будет еще кастомный аллокатор, выделяющий куски для векторов из разделяемой памяти, и заботящийся о разных адресах в разных процессах.

Я думаю, проще написать свой шаблонный контейнер, чем адаптировать STL.

anonymous ()

Вот есть вектор. Вектор, например, внутри хранит указатель на массив. Указатель - это охуенно, но в другом процессе указатель на те же данные будет численно другой. И как ты собрался это заставить работать?

Pavval ★★★★★ ()
Ответ на: комментарий от Pavval

Ну вот boost::ipc это как-то делают через кастомный алокатор. Тоже самое говорится в статье на Dr.Dobb, но там так же «не все так прозрачно» для меня. Т.е. я так понимаю не вариант и лучше даже не париться с этими «хотелками».

netcreeper ()

Сам не юзал, но есть вот такой велосипед:

https://capnproto.org/

Inter-process communication: Multiple processes running on the same machine can share a Cap’n Proto message via shared memory. No need to pipe data through the kernel. Calling another process can be just as fast and easy as calling another thread.

PS Я, кстати, за вариант «не форкаться без необходимости».

asaw ★★★★★ ()
Последнее исправление: asaw (всего исправлений: 1)
Ответ на: комментарий от netcreeper

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

Iron_Bug ★★★★ ()
Ответ на: комментарий от anonymous

Проще всего мапить сегмент на один и тот же адрес во всех процессах. Тогда указатели на объекты, размещённые в этом сегменте, будут валидными во всех процессах. Тогда можно использовать стандартные контейнеры со своим аллокатором. А аллокатор можно реализовать с помощью glibc-оного маллока в отдельной арене, использующей сегмент.

iliyap ★★★★★ ()
Ответ на: комментарий от Pavval

Если все процессы родственные, то есть форкнуты от единого предка, этот предок может смапить сегмент до форка, и во всех потомках этот сегмент будет с одним и тем же адресом. И во всех потомках указатели внутрь сегмента будут одинаковые.

iliyap ★★★★★ ()

Используй третий вариант. Остальное - продукт компании костьіль&костьіли

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.