Я хочу поделиться памятью, используя дескриптор файла, с другим процессом, созданным через fork
.
Проблема в том, что я получаю разные регионы адресов от mmap
.
Я хочу, чтобы mmap
возвращал то же значение адреса. Только в этом случае я могу быть уверен, что я действительно разделяю память.
Возможно, можно использовать MAP_FIXED
флаг для mmap
, но как получить адрес памяти из shm_open
?
Можно ли вообще разделить память через shm_open
?
Может быть, вместо этого следует использовать shmget
Это минимальный рабочий пример:
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
int main(void)
{
/* Create a new memory object */
int fd = shm_open( "/dummy", O_RDWR | O_CREAT, 0777 );
if(fd == -1) {
fprintf(stderr, "Open failed:%m\n");
return 1;
}
/* Set the memory object's size */
size_t size = 4096; /* minimal */
if (ftruncate(fd, size) == -1) {
fprintf(stderr, "ftruncate: %m\n");
return 1;
}
void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) return 1;
void *ptr2 = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr2 == MAP_FAILED) return 1;
printf("%p\n%p\n", ptr, ptr2);
return 0;
}
Скомпилируйте его с помощью gcc test.c -lrt
.
Это вывод:
0x7f3247a78000
0x7f3247a70000
EDIT
Если я попытаюсь использовать метод, описанный в комментарии, child не увидит изменений в памяти, сделанных родительским. Зачем? Вот как я это делаю:
В родительском:
shm_data = mmap(NULL, shm_size, PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
...
snprintf(shared_memory, 20, "%p", shm_data);
execl("/path/to/prog", "prog", shared_memory, (char *) NULL);
у ребенка:
...
void *base_addr;
sscanf(argv[1], "%p", (void **)&base_addr);
shm_data = mmap(base_addr, shm_size, PROT_READ, MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED, -1, 0);
...
EDIT2
См. Также этот вопрос: Как получить адрес памяти из memfd_create?