在 Mac OS X 上使用 mmap 实现写时复制缓冲区
Implementing copy-on-write buffer with mmap on Mac OS X
我一直在研究 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
调用 returns MAP_FAILED
,errno
= 22 (EINVAL
) . OS X man page for mmap
似乎表明这应该有效(它甚至在 MAP_PRIVATE
标志的描述中提到了写时复制),并且我已经尝试了各种不同的标志来调用 mmap
,但似乎没有任何效果。有什么想法吗?
似乎将 shm_open
与 MAP_SHARED
和 MAP_PRIVATE
一起使用会对文件描述符产生不良影响。使用 open
是一种可能的解决方法:
int fd = open(SHM_NAME, O_RDWR | O_CREAT, 0666);
...
结果:
munmap(buf2): 0
munmap(buf1): 0
shm_unlink: -1
将 shm_open
与 MAP_SHARED
和 MAP_PRIVATE
一起使用会导致 Invalid file descriptor
,尽管将其与 MAP_SHARED
和 MAP_SHARED
一起使用会产生 Invalid file descriptor
不是。我不清楚这是一个错误,还是设计使然 - 虽然这种行为似乎不正确。
我一直在研究 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
调用 returns MAP_FAILED
,errno
= 22 (EINVAL
) . OS X man page for mmap
似乎表明这应该有效(它甚至在 MAP_PRIVATE
标志的描述中提到了写时复制),并且我已经尝试了各种不同的标志来调用 mmap
,但似乎没有任何效果。有什么想法吗?
似乎将 shm_open
与 MAP_SHARED
和 MAP_PRIVATE
一起使用会对文件描述符产生不良影响。使用 open
是一种可能的解决方法:
int fd = open(SHM_NAME, O_RDWR | O_CREAT, 0666);
...
结果:
munmap(buf2): 0
munmap(buf1): 0
shm_unlink: -1
将 shm_open
与 MAP_SHARED
和 MAP_PRIVATE
一起使用会导致 Invalid file descriptor
,尽管将其与 MAP_SHARED
和 MAP_SHARED
一起使用会产生 Invalid file descriptor
不是。我不清楚这是一个错误,还是设计使然 - 虽然这种行为似乎不正确。