【问题标题】:How can I share existing memory with shm_open?如何与 shm_open 共享现有内存?
【发布时间】:2014-03-17 20:35:19
【问题描述】:

在 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() 它,这两个进程将共享同一块内存。
  • 步骤 1. 假设我们在 0x1000 具有 RWX 权限和 MAP_PRITAVE|MAP_ANONYMOUS 标志的映射内存区域。步骤 2. 我们在内存地址 0x1000 处写入一些数据。步骤 3. 我们希望与另一个进程共享 0x1000(虚拟地址必须为 0x1000)处的内存内容。我被困在第 3 步。

标签: c linux shared-memory


【解决方案1】:

您的代码确实共享内存,但您的两个进程将获得不同的地址区域。您希望拥有相同的区域,因此 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;
}

【讨论】:

    猜你喜欢
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 2023-03-19
    相关资源
    最近更新 更多