2010-01-18 1 views
4

У меня есть два процесса P1 и P2.Два приложения на C++, разделяющие область памяти только для чтения на Linux

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

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

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

Любое знакомое, как это сделать/gotchas?

+0

См. Также: http://stackoverflow.com/questions/2080281/how-do-mmap-a-particular-region-in-memory. Ни в коем случае не прямой дубликат, а тесно связанный. –

ответ

5

Вообще-то подобное было asked and solved before:

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

1

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

+1

Адресация может быть упрощена, если макет известен заранее, тогда достаточно простой структуры, которая описывает это. Если нет, то адресная таблица для объектов может помочь - создайте один раз для каждого процесса и раздайте его по мере необходимости. –

0

Его так легко, как это:

#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-совместимой системе.

1

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

Смежные вопросы