c - 在 Mac OS X 上使用 mmap 实现写时复制缓冲区

标签 c macos mmap copy-on-write

我一直在 Linux 上使用写时复制缓冲区,下面的示例似乎按预期工作:

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

#define SIZE 4096

#define SHM_NAME "foobar"

int main(void)
{
    int fd = shm_open(SHM_NAME, O_RDWR | O_CREAT, 0666);
    int r = ftruncate(fd, SIZE);

    char *buf1 = mmap(NULL, SIZE, PROT_READ | PROT_WRITE,
                     MAP_SHARED, fd, 0);

    strcpy(buf1, "Original buffer");

    char *buf2 = mmap(NULL, SIZE, PROT_READ | PROT_WRITE,
                      MAP_PRIVATE, fd, 0);

    // At this point buf2 is aliased to buf1

    // Now modifying buf2 should trigger copy-on-write)...

    strcpy(buf2, "Modified buffer");

    // buf1 and buf2 are now two separate buffers

    strcpy(buf1, "Modified original buffer");

    // clean up

    r = munmap(buf2, SIZE);
    printf("munmap(buf2): %i\n", r);
    r = munmap(buf1, SIZE);
    printf("munmap(buf1): %i\n", r);
    r = shm_unlink(SHM_NAME);
    printf("shm_unlink: %i\n", r);

    return EXIT_SUCCESS;
}

但是在 OS X (10.10) 下,第二个 mmap 调用返回 MAP_FAILEDerrno = 22 (EINVAL). OS X man page for mmap似乎表明这应该有效(它甚至在 MAP_PRIVATE 标志的描述中提到了写时复制),并且我已经尝试了各种不同的标志来调用 mmap,但似乎没有任何效果。有什么想法吗?

最佳答案

似乎将 shm_openMAP_SHAREDMAP_PRIVATE 一起使用会对文件描述符产生不良影响。使用 open 是一种可能的解决方法:

int fd = open(SHM_NAME, O_RDWR | O_CREAT, 0666);
...

结果:

munmap(buf2): 0
munmap(buf1): 0
shm_unlink: -1

shm_openMAP_SHAREDMAP_PRIVATE 一起使用会导致 无效文件描述符,尽管将其与 一起使用>MAP_SHAREDMAP_SHARED 例如没有。我不清楚这是一个错误还是设计使然 - 尽管该行为似乎不正确。

关于c - 在 Mac OS X 上使用 mmap 实现写时复制缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29037110/

相关文章:

c - 如何在 OS X Mavericks 上使用 Clang 设置自定义 C 入口点?

postgresql - Brew Postgresql 启动但进程未运行

c++ - 如何在多线程中关闭 malloc() 的 mmap 使用?

c - C 中的 R3Route URL 路由器

python - 为什么 python 实现使用的内存比 C 多 9 倍?

c - 用C语言读取内存块

go - syscall.Mmap的实现

c - "while(*s++ = *t++)"如何复制一个字符串?

macos - NSToolbarItem 的自动样式/着色

memory - windows平台上是否有内存映射api,就像linux上的mmap()一样?