【发布时间】:2019-05-04 00:18:19
【问题描述】:
使用 mmap 时,共享内存的最小大小是多少?我需要创建一个内存大小足够小的程序,它最多可以读取(或保存)几个字符。我该怎么做?
将大小更改为 1、2 或 4 时,它仍会读取整个字符串。
我基于How to use shared memory with Linux in C
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
void* create_shared_memory(size_t size) {
int protection = PROT_READ | PROT_WRITE;
int visibility = MAP_ANONYMOUS | MAP_SHARED;
return mmap(NULL, size, protection, visibility, 0, 0);
}
#include <string.h>
#include <unistd.h>
int main() {
char* parent_message = "hello"; // parent process will write this message
char* child_message = "goodbye"; // child process will then write this one
void* shmem = create_shared_memory(128);
memcpy(shmem, parent_message, sizeof(parent_message));
int pid = fork();
if (pid == 0) {
printf("Child read: %s\n", shmem);
memcpy(shmem, child_message, sizeof(child_message));
printf("Child wrote: %s\n", shmem);
} else {
printf("Parent read: %s\n", shmem);
sleep(1);
printf("After 1s, parent read: %s\n", shmem);
}
}
【问题讨论】:
-
sizeof parent_message是sizeof(char*)。并且 mmap() 在内存页面(主要是 4096 字节)中计数,因此您的大小(4 或 8)会向上取整,(但在读取/写入实际磁盘文件时会丢弃尾部) -
如果您希望
sizeof按预期工作,请使用const char parent_message[] = "hello";。它将包括终止NULL字符。这同样适用于child_message。在这种情况下,我认为最好使用在指针上失败的COUNTOF宏。类似Array-size macro that rejects pointers。 -
这些看起来也有问题:
printf("Child read: %s\n", shmem);(和朋友)。我看不到您用NULL终止复制的字符串的位置。