Два приложения C ++, разделяющие область памяти только для чтения в Linux - PullRequest
5 голосов
/ 18 января 2010

У меня есть два процесса P1 и P2.

У меня есть этот большой ресурс только для чтения, который называется «R», и я хочу, чтобы и P1, и P2 имели к нему доступ.

R - это не просто плоская группа байтов; это группа объектов C ++, которые указывают друг на друга.

Я бы предпочел, чтобы P1 и P2 разделяли только одну копию R - каким-то образом P1 загружает R в область памяти (которая отображается в P1 и P2 по одному и тому же адресу), тогда P1 и P2 могут оба обращаться к объектам в R как объекты C ++ (без условий гонки, так как все доступно только для чтения).

Кто-нибудь знает, как это сделать / получил?

Ответы [ 4 ]

5 голосов
/ 18 января 2010

На самом деле нечто подобное спрашивалось и решалось раньше :

И лучший ответ, вероятно, будет работать для вас: используйте boost interprocess library .Хотя вы все еще не можете использовать объекты с виртуальными функциями (неприятный указатель vtable вне проблемы с общей памятью), у них есть инструменты, позволяющие вам использовать интеллектуальные указатели на другие объекты в общей памяти, и пользовательские распределители, которые выделяются в общей памяти для созданияобъекты std :: vector и std :: map.

1 голос
/ 18 января 2010

Если я понимаю man-страницу, похоже, что функция Linux mmap позволяет вам сопоставить файл, общую память или другую сопоставляемую вещь с вашим процессом по определенному виртуальному адресу если вы предоставите несколько пугающую опцию MAP_FIXED. Найдите на странице man MAP_FIXED, и вы найдете много предупреждений (может не поддерживаться, может привести к тому, что malloc больше не будет работать и т. Д.). Но если бы вы могли заставить его работать, общие объекты могли бы иметь указатели друг на друга.

1 голос
/ 18 января 2010

Как объекты внутри R указывают друг на друга? Если его позиция «относительно текущих объектов», вы можете использовать shared memory . Нет никакой гарантии, что эта общая память загружена внутри обоих процессов P1 и P2 в одном и том же месте адреса. Вот почему родственник только работает. И поскольку вы сказали, что никто из них не будет пытаться изменить его и просто прочитать его, я думаю, вам не нужно защищать его, используя семафор / мьютекс.

0 голосов
/ 18 января 2010

Это так же просто, как это:

#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>

// ...

int fd = open("memfile.txt",O_RDWR);
struct stat info;
fstat(fd, &info);
void * page = mmap(0, info.st_size, PROT_READ , MAP_SHARED, fd, 0);

Теперь вы можете использовать все, что вы сохранили в memfile.txt в качестве структуры, и это будет использоваться всеми процессами.

ПРИМЕЧАНИЕ , как говорили другие, вы не можете использовать указатели между объектами внутри этого фрагмента памяти.

Это работает для меня на OS X 10.4, но должно работать на любой BSD-совместимой системе.

...