在Mac OS X上使用mmap实现copy-on-write缓冲区

Pau*_*l R 5 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;
}
Run Code Online (Sandbox Code Playgroud)

但是在OS X(10.10)下,第二次mmap调用返回MAP_FAILED,errno= 22(EINVAL).在OS X的手册页mmap似乎表明,这应该工作(它甚至提到写入时复制中的描述MAP_PRIVATE标志),我已经与调用各种不同的标志尝试mmap,但似乎没有任何工作.有任何想法吗 ?

l'L*_*L'l 5

看来使用shm_openwithMAP_SHAREDMAP_PRIVATE对文件描述符做了一些不受欢迎的事情。使用open是一种可能的解决方法:

int fd = open(SHM_NAME, O_RDWR | O_CREAT, 0666);
...
Run Code Online (Sandbox Code Playgroud)

结果:

munmap(buf2): 0
munmap(buf1): 0
shm_unlink: -1
Run Code Online (Sandbox Code Playgroud)

shm_openMAP_SHAREDand一起使用MAP_PRIVATE会产生,但与andInvalid file descriptor一起使用则不会。我不清楚这是一个错误,还是设计使然 - 但这种行为似乎并不正确。MAP_SHAREDMAP_SHARED

  • 谢谢 - 使用常规文件从 `shm_open` 切换到 `open` 解决了我的问题! (2认同)