Разделяемая память без блокировки в C++ для записей переменной длины

Я новичок в IPC. Процесс записи записывает данные в разделяемую память, многие процессы чтения считывают данные. Записываемые данные имеют уникальный идентификатор, должны быть проиндексированы уникальным ключом для более быстрого доступа (например, STL::map или hashmap для поиска). Также данные представляют собой запись переменной длины (XML) (средняя длина 200-250 байт). ОС Solaris 10 (i86pc) на четырехъядерном сервере Intel Xeon.

Общий размер данных составляет более 200G. Но мы будем хранить в общей памяти только последние данные. Исторические данные находятся в файле. размер общей памяти будет около 4G~6G.

Нет доступной внешней библиотеки, такой как Boost::interprocess

У меня есть пара вопросов, может быть много

  1. Что эффективнее: shared_memory или mmap (файлы с отображением памяти)
  2. Как построить индексы для записи переменной длины. [Понятия не имею, может быть какое-то хеширование?].
  3. Будет ли это аккуратно, если XML будет преобразован в структуру фиксированного размера (компромисс - размер структуры будет огромным, почти 300+ возможных полей)
  4. Можем ли мы поместить любой STL в общую_память, предоставив пользовательский распределитель?
  5. Возможна ли реализация без семафоров (безблокировочная реализация с использованием CAS).

Спасибо

Как насчет этого.

|--------------------------|
| start_id   |   end_id    |   ->  range of msg id present in the segment
|--------------------------|
| id1 | start_mem | length |   ->
|--------------------------|   ->
| id2 | start_mem | length |   -> table of index for the actual data
|--------------------------|   ->
| id3 | start_mem | length |   ->
|--------------------------|   ->
| id4 | start_mem | length |   ->
|--------------------------|   ->
|                          |
|                          |
|                          |
|       data segment       |
|       varibale length    |
|       xml are stored     |
|                          |
|                          |
|--------------------------|

При поступлении новых данных и заполнении сегмента. самые старые данные стираются по кругу. Может быть возможность стереть более 1 записи.


person naveenhegde    schedule 02.02.2012    source источник
comment
какой компилятор вы используете?   -  person pyCthon    schedule 02.02.2012
comment
Пожалуйста, сделайте так, чтобы ваш заголовок описывал вопрос. На самом деле, пока мы на этом, это пять вопросов. Разместите их как таковые.   -  person Lightness Races in Orbit    schedule 02.02.2012
comment
Должны ли ваши читатели читать одни и те же данные? Фиксировано ли количество ключей для всех процессов?   -  person Karlson    schedule 02.02.2012
comment
Да, все читатели должны читать одни и те же данные. Но некоторые могут быть быстрее в потреблении, некоторые могут быть немного медленнее из-за некоторых операций, которые читатель выполняет с данными. (эти операции различаются между читателями)   -  person naveenhegde    schedule 02.02.2012
comment
Каковы ваши требования к индексации?   -  person bdonlan    schedule 03.02.2012


Ответы (2)


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

Если вы не выберете этот маршрут, имейте в виду, что общая память жесткая. То, что вы просите, определенно выполнимо в общей памяти - вы можете создать распределитель кучи в этом блоке shmem и т. д. Распределители STL могут работать, но не ожидайте, что сторонние библиотеки будут довольны Распределители STL, использующие пользовательские типы указателей. Вам потребуются блокировки (если вы сообразительны, то сможете избежать их в некоторых случаях, но не во всех, и в этом случае обязательно попрощайтесь с STL), и вам придется пересобрать все, что вы обычно принимаете как должное.

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

person bdonlan    schedule 03.02.2012
comment
В качестве немедленных решений Архитектура SOA невозможна. После публикации этого вопроса я узнал, что мы не можем размещать STL в shared_memory (он использует указатели, которые не видны другим процессам) - person naveenhegde; 03.02.2012
comment
Почему в вашем случае невозможен мастер-процесс? - person bdonlan; 03.02.2012
comment
Пожалуйста, ответьте на вопрос, чтобы другие люди искали решение - person Alex; 17.10.2017

Возможна ли реализация без семафоров (безблокировочная реализация с использованием CAS).

Поскольку реализации без блокировки (lock-free) сложно проектировать, и мы можем столкнуться с хаосом, прежде чем перейти к решению без блокировки, вы должны рассмотреть следующие аспекты и альтернативы:

  • Если в системе много потоков, то планировщик, вероятно, вытеснит поток, удерживающий блокировку, следовательно, все остальные потоки будут ожидать блокировки (если нет, то отсутствие блокировки не даст значительного улучшения).
  • Если это можно решить с помощью блокировки чтения-записи. (писателей значительно меньше, чем читателей).
  • Если конкуренция за блокировку менее вероятна, вы можете рассмотреть спин-блокировки, которые дадут вам такую ​​​​же производительность, как и без блокировки.
person peeyush    schedule 02.02.2012
comment
Пожалуйста, ответьте на вопрос, чтобы другие люди искали решение - person Alex; 17.10.2017