如何使用shm_open共享已存在的内存?

8
在Linux中,我想要将我的进程的一些内存内容与其他进程共享。其中一种方法是使用shm_open和mmap。就像下面这样。
/* Create a new memory object */
fd = shm_open( "/bolts", O_RDWR | O_CREAT, 0777 );
if( fd == -1 ) {
    fprintf( stderr, "Open failed:%s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

/* Set the memory object's size */
if( ftruncate( fd, sizeof( *addr ) ) == -1 ) {
    fprintf( stderr, "ftruncate: %s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

/* Map the memory object */
addr = mmap( 0, sizeof( *addr ),
        PROT_READ | PROT_WRITE,
        MAP_SHARED, fd, 0 );
if( addr == MAP_FAILED ) {
    fprintf( stderr, "mmap failed: %s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

然而,这样做的话,我无法共享“已分配的内存”。 我的问题是:我能在不重新分配它们的情况下共享先前分配的内存内容吗? 谢谢您的帮助。

很难理解你所说的“已分配内存”和“先前分配的内存”的含义。如果你想共享这块内存,只需让另一个进程打开/bolts路径并使用mmap()函数映射它,两个进程将共享同一块内存。 - nos
阅读shm_overview(7) - Basile Starynkevitch
步骤1:假设我们在0x1000处拥有具有RWX权限和MAP_PRIVATE | MAP_ANONYMOUS标志的mmap内存区域。步骤2:我们在内存地址0x1000处写入一些数据。步骤3:我们想要与另一个进程共享0x1000处的内存内容(虚拟地址必须为0x1000)。我卡在第3步了。 - daehee
1个回答

3

您的代码确实共享内存,但是您的两个进程将获得不同的地址区域。您希望拥有相同的区域,因此addr值将是相同的。在这种情况下,您可以在此内存中构建对象,使用内部指针,您的对象将在两个进程中有效且可见。

有两种方法可以实现这一点。

1)使用fork()创建另一个进程

2)请求mmap在特殊地址分配内存并使用MAP_FIXED

对于第二种方法,您的代码将如下所示:

/* Create a new memory object */
fd = shm_open( "/bolts", O_RDWR | O_CREAT, 0777 );
if( fd == -1 ) {
    fprintf( stderr, "Open failed:%s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

/* Set the memory object's size */
if( ftruncate( fd, sizeof( *addr ) ) == -1 ) {
    fprintf( stderr, "ftruncate: %s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

// You base address for memory region that you want to share. 
// Choose this carefully, you both processes MUST have it available!
void * baseAddr = 0x7fff00000000; 

/* Map the memory object */
addr = mmap( baseAddr, sizeof( *addr ),
        PROT_READ | PROT_WRITE,
        MAP_SHARED | MAP_FIXED, fd, 0 );

if( addr == MAP_FAILED | MAP_FIXED ) {
    fprintf( stderr, "mmap failed: %s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

image


根据Posix和Linux的manpage,MAP_FIXED将用新内存替换位置处的任何现有内存——即它不会共享现有内存。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接