【问题标题】:Sharing memory between processes on linuxlinux进程间共享内存
【发布时间】:2023-06-25 23:53:01
【问题描述】:

我有服务器,它使用多个进程 (fork())。有大块数据,可以由一个进程创建,并且应该在其他进程之间共享。

所以,我使用 shm_open + mmap 创建共享内存并将其映射到虚拟内存。

struct SharedData {
    const char *name;
    int descriptor;
    void *bytes;
    size_t nbytes;
}

void shared_open(SharedData *data, const char *name, size_t nbytes) {
    int d = shm_open(name, O_RDONLY, S_IRUSR | S_IWUSR);
    if (d != -1) {
        void *bytes = mmap(NULL, nbytes, PROT_READ, MAP_SHARED, d, 0 );
        data->name = name;
        data->descriptor = d;
        data->bytes = bytes;
        data->nbytes = nbytes;
    } else {
        data->descriptor = -1;
    }
}

void shared_create(SharedData *data, const char *name, void *bytes, size_t nbytes) {
    int d = shm_open(name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    if (d != -1) {
        if (nbytes = write(d, bytes, nbytes)) {
            shared_open(data, name, nbytes);
        }
        shm_unlink(name);
    }
}

void shared_close(SharedData *data) {
    if (data->descriptor != -1) {
        munmap(data->bytes, data->nbytes);
        shm_unlink(data->name);
    }
}

初始进程用shared_create创建共享内存对象,其他进程用shared_open打开它

这种方法有效吗?有没有更有效或更简单的方法?

【问题讨论】:

  • 您知道fork 使用写时复制策略吗?内存页是共享的,直到其中一个进程修改它?
  • 一次只有一个进程可以创建共享数据,其他进程只读。共享数据只有在fork阶段后才能创建
  • 您的代码实现是否有具体问题?如果不是,您的问题属于Code Review 网站。

标签: c linux posix shared-memory mmap


【解决方案1】:

您的设计看起来很合理。要保持在 API 的 POSIX 准则范围内共享内存,您应该使用 ftruncate 而不是 write 来扩展大小,请参阅

http://man7.org/linux/man-pages/man7/shm_overview.7.html

你总是可以做一个 memcpy 来初始化内容。

如果你使用的是c++,你可以使用boost interprocess,如果没有别的,你可以看看他们的接口。

http://www.boost.org/doc/libs/1_51_0/doc/html/interprocess/sharedmemorybetweenprocesses.html

【讨论】: