【问题标题】:How to use shm_open with mmap properly如何正确使用 shm_open 和 mmap
【发布时间】:2016-04-30 09:38:18
【问题描述】:

我正在尝试使用我在网上找到的示例和文档来创建共享内存区域。我的目标是 IPC ,所以我可以让不同的进程相互通信。

这是我的 C 文件

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>

int main (int argc, char *argv[])
{

struct stat sb;
off_t len;
char *p;
int fd;

fd = shm_open("test",  O_RDWR | O_CREAT); //,S_IRUSR | S_IWUSR);

if (fd == -1) {
    perror("open");
    return 1;
}

if (fstat(fd, &sb)==-1){
    perror("fstat");
    return 1;
}

/*if (!S_ISREG(sb.st_mode)){
    fprintf(stderr, "%s is not a file\n",fileName);
    return 1;
}*/

p = mmap(0, sb.st_size, PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED){
    perror("mmap");


    return 1;

}

if (close(fd)==-1) {
    perror("close");
    return 1;

}
for (len = 0; len < sb.st_size; len++) {
    putchar(p[len]);

}

if (munmap(p, sb.st_size) == -1) {
    perror("munmao");
    return 1;
}
fprintf(stderr,"\n");
return 0;
}

问题是我得到一个 mmap: Invalid argument。我认为 fd 有问题,但不知道如何修复它,任何帮助将不胜感激。我正在使用最新的 XCODE 在优胜美地。

【问题讨论】:

    标签: c macos shared-memory mmap


    【解决方案1】:

    您需要扩展共享内存映射的大小,至少在您第一次创建它时。现在它的大小为 0,并且 mmap 不允许您进行零长度映射。

    因此,不要调用 fstat(),而是执行例如:

    size_t len = 4096;
    if (ftruncate(fd, len) == -1) {
        perror("ftruncate");
        return 1;
    }
    

    并将这个len 传递给 mmap()。

    【讨论】:

    • 恐怕你的代码不起作用,它给了我“ftruncate: Invalid argument”
    • 好的,它在 linux 上运行良好,似乎 OSX 对 shm_open/ftruncate 有一些奇怪的行为,请参阅 stackoverflow.com/questions/25502229/…(即你已经运行了你的程序好几次了,所以你需要首先删除该段。此外,您的 shm_open 调用需要您注释掉的 3. 参数 hm_open("test", O_RDWR | O_CREAT,S_IRUSR | S_IWUSR););
    • 感谢您的帮助。我已经将这些片段注释掉了,只是为了测试目的,即使包含它们,我也尝试过。我想我会坚持只使用 open 并避免使用 shm_open,因为我决定我也想将我的共享内存存储到一个文件中作为 msync 的备份。
    【解决方案2】:

    您的addr 参数设置为0,这可能是保留的。您的意思是使用NULL 吗?这将不同于 0

    【讨论】:

    • 我也投反对票,因为您需要先了解 mmap 的工作原理,然后再提供答案。 0 是 mmap 最常用的地址,如果该地址被占用,内核将找到一个空闲地址。
    猜你喜欢
    • 2013-12-28
    • 1970-01-01
    • 2012-09-18
    • 2019-11-28
    • 2016-03-10
    • 2018-07-26
    • 2021-09-14
    • 2016-07-03
    • 1970-01-01
    相关资源
    最近更新 更多