Доступ к данным в общей памяти C ++ POSIX - PullRequest
1 голос
/ 16 ноября 2011

Я открываю часть общей памяти и получаю ручку. Я знаю, что в памяти хранится несколько векторов данных. Я хотел бы получить доступ к этим векторам данных и выполнить некоторые действия с ними. Как мне этого добиться? Целесообразно ли рассматривать разделяемую память как объект, чтобы мы могли определять эти векторы как поля объекта, а необходимые действия - как функции-члены объекта?

Я никогда раньше не имел дело с общей памятью. Что еще хуже, я новичок в C ++ и POSIX. Может ли кто-нибудь дать несколько советов? Простые примеры будут с благодарностью.

1 Ответ

0 голосов
/ 17 ноября 2011
int my_shmid = shmget(key,size,shmflgs);
...
void* address_of_my_shm1 = shat(my_shmid,0,shmflags);

Object* optr = static_cast<Object*>(address_of_my_shm1);

... или, в каком-то другом потоке / процессе, которому вы договорились передать address_of_my_shm1 ... каким-то другим способом

void* address_of_my_shm2 = shat(my_shmid,address_of_my_shm1,shmflags);

Вы можете утверждать, что address_of_shm1 == address_of_shm2. Но обратите внимание, что я говорю «может» - вам на самом деле не нужно это делать. Некоторые типы / структуры / классы можно одинаково хорошо читать по разным адресам.

Если объект появится в разных адресных пространствах, то указатели за пределами shhm в процессе A могут не указывать на то же самое, что и в процессе B. В общем, указатели за пределами shm плохие. (Виртуальные функции - это указатели вне объекта и вне его. Плохо, если у вас нет другой причины доверять им.)

Указатели внутри ШМ можно использовать, если они появляются по тому же адресу.

Относительные указатели могут быть весьма полезными, но, опять же, до тех пор, пока они указывают только внутри ШМ. Относительные указатели могут относиться к основанию объекта, то есть они могут быть смещениями. Или они могут быть относительно самого указателя. Вы можете определить несколько хороших классов / шаблонов, которые будут выполнять эти вычисления, при этом приведение будет происходить изнутри.

Совместное использование объектов через shmem проще всего, если данные являются просто POD (Plain Old Data). Ничего особенного.

Поскольку вы находитесь в разных процессах, которые не разделяют все адресное пространство, вы не можете быть уверены, что такие вещи, как виртуальные функции, будут появляться по одному и тому же адресу во всех процессах, использующих сегмент общей памяти shm. Поэтому, вероятно, лучше избегать виртуальных функций. (Если вы очень стараетесь и / или знаете связь, в некоторых случаях вы можете использовать виртуальные функции. Но это одна из первых вещей, которую я бы отключил, если бы мне пришлось отлаживать.)

Это следует делать только в том случае, если вам известна модель объектной памяти вашей реализации. И если расширенные (для C ++) оптимизации, такие как разбиение структур на отдельные горячие и холодные части, отключены. Поскольку такая оптимизация, возможно, недопустима для C ++, вы, вероятно, в безопасности.

Очевидно, что вам лучше, если вы применяете один и тот же тип / класс объекта со всех сторон. Вы можете уйти с не виртуальными функциями. Тем не менее, обратите внимание, что может быть довольно легко иметь один и тот же класс, но разные версии класса - например, различающиеся по размеру, например добавление нового поля и изменение смещений всех остальных полей - поэтому вам нужно быть очень осторожным, чтобы все стороны использовали одинаковые определения и объявления.

...